semaphore.java
来自「SRI international 发布的OAA框架软件」· Java 代码 · 共 809 行 · 第 1/3 页
JAVA
809 行
if (Thread.interrupted()) throw new InterruptedException();
if (precheck()) return;
WaitQueue.WaitNode w = new WaitQueue.WaitNode();
w.doWait(this);
}
public boolean attempt(long nanos) throws InterruptedException {
if (Thread.interrupted()) throw new InterruptedException();
if (precheck()) return true;
if (nanos <= 0) return false;
WaitQueue.WaitNode w = new WaitQueue.WaitNode();
return w.doTimedWait(this, nanos);
}
protected synchronized boolean precheck() {
boolean pass = (permits_ > 0);
if (pass) --permits_;
return pass;
}
public synchronized boolean recheck(WaitQueue.WaitNode w) {
boolean pass = (permits_ > 0);
if (pass) --permits_;
else wq_.insert(w);
return pass;
}
public void takeOver(WaitQueue.WaitNode n) {}
protected synchronized WaitQueue.WaitNode getSignallee() {
WaitQueue.WaitNode w = wq_.extract();
if (w == null) ++permits_; // if none, inc permits for new arrivals
return w;
}
public void release() {
for (;;) {
WaitQueue.WaitNode w = getSignallee();
if (w == null) return; // no one to signal
if (w.signal(this)) return; // notify if still waiting, else skip
}
}
/** Release N permits **/
public void release(int n) {
if (n < 0) throw new IllegalArgumentException("Negative argument");
for (int i = 0; i < n; ++i) release();
}
public synchronized boolean hasQueuedThreads() {
return wq_.hasNodes();
}
public synchronized int getQueueLength() {
return wq_.getLength();
}
public synchronized Collection getQueuedThreads() {
return wq_.getWaitingThreads();
}
}
/**
* Creates a <tt>Semaphore</tt> with the given number of
* permits and nonfair fairness setting.
* @param permits the initial number of permits available. This
* value may be negative, in which case releases must
* occur before any acquires will be granted.
*/
public Semaphore(int permits) {
impl = new NonfairImpl(permits);
}
/**
* Creates a <tt>Semaphore</tt> with the given number of
* permits and the given fairness setting.
* @param permits the initial number of permits available. This
* value may be negative, in which case releases must
* occur before any acquires will be granted.
* @param fair true if this semaphore will guarantee first-in
* first-out granting of permits under contention, else false.
*/
public Semaphore(int permits, boolean fair) {
impl = (fair)? (Impl)new FairImpl(permits) : new NonfairImpl(permits);
}
/**
* Acquires a permit from this semaphore, blocking until one is
* available, or the thread is {@link Thread#interrupt interrupted}.
*
* <p>Acquires a permit, if one is available and returns immediately,
* reducing the number of available permits by one.
* <p>If no permit is available then the current thread becomes
* disabled for thread scheduling purposes and lies dormant until
* one of two things happens:
* <ul>
* <li>Some other thread invokes the {@link #release} method for this
* semaphore and the current thread is next to be assigned a permit; or
* <li>Some other thread {@link Thread#interrupt interrupts} the current
* thread.
* </ul>
*
* <p>If the current thread:
* <ul>
* <li>has its interrupted status set on entry to this method; or
* <li>is {@link Thread#interrupt interrupted} while waiting
* for a permit,
* </ul>
* then {@link InterruptedException} is thrown and the current thread's
* interrupted status is cleared.
*
* @throws InterruptedException if the current thread is interrupted
*
* @see Thread#interrupt
*/
public void acquire() throws InterruptedException {
impl.acquire();
}
/**
* Acquires a permit from this semaphore, blocking until one is
* available.
*
* <p>Acquires a permit, if one is available and returns immediately,
* reducing the number of available permits by one.
* <p>If no permit is available then the current thread becomes
* disabled for thread scheduling purposes and lies dormant until
* some other thread invokes the {@link #release} method for this
* semaphore and the current thread is next to be assigned a permit.
*
* <p>If the current thread
* is {@link Thread#interrupt interrupted} while waiting
* for a permit then it will continue to wait, but the time at which
* the thread is assigned a permit may change compared to the time it
* would have received the permit had no interruption occurred. When the
* thread does return from this method its interrupt status will be set.
*
*/
public void acquireUninterruptibly() {
boolean wasInterrupted = false;
while (true) {
try {
impl.acquire();
if (wasInterrupted) {
Thread.currentThread().interrupt();
}
return;
}
catch (InterruptedException e) {
wasInterrupted = true;
}
}
}
/**
* Acquires a permit from this semaphore, only if one is available at the
* time of invocation.
* <p>Acquires a permit, if one is available and returns immediately,
* with the value <tt>true</tt>,
* reducing the number of available permits by one.
*
* <p>If no permit is available then this method will return
* immediately with the value <tt>false</tt>.
*
* <p>Even when this semaphore has been set to use a
* fair ordering policy, a call to <tt>tryAcquire()</tt> <em>will</em>
* immediately acquire a permit if one is available, whether or not
* other threads are currently waiting.
* This "barging" behavior can be useful in certain
* circumstances, even though it breaks fairness. If you want to honor
* the fairness setting, then use
* {@link #tryAcquire(long, TimeUnit) tryAcquire(0, TimeUnit.SECONDS) }
* which is almost equivalent (it also detects interruption).
*
* @return <tt>true</tt> if a permit was acquired and <tt>false</tt>
* otherwise.
*/
public boolean tryAcquire() {
return impl.attempt();
}
/**
* Acquires a permit from this semaphore, if one becomes available
* within the given waiting time and the
* current thread has not been {@link Thread#interrupt interrupted}.
* <p>Acquires a permit, if one is available and returns immediately,
* with the value <tt>true</tt>,
* reducing the number of available permits by one.
* <p>If no permit is available then
* the current thread becomes disabled for thread scheduling
* purposes and lies dormant until one of three things happens:
* <ul>
* <li>Some other thread invokes the {@link #release} method for this
* semaphore and the current thread is next to be assigned a permit; or
* <li>Some other thread {@link Thread#interrupt interrupts} the current
* thread; or
* <li>The specified waiting time elapses.
* </ul>
* <p>If a permit is acquired then the value <tt>true</tt> is returned.
* <p>If the current thread:
* <ul>
* <li>has its interrupted status set on entry to this method; or
* <li>is {@link Thread#interrupt interrupted} while waiting to acquire
* a permit,
* </ul>
* then {@link InterruptedException} is thrown and the current thread's
* interrupted status is cleared.
* <p>If the specified waiting time elapses then the value <tt>false</tt>
* is returned.
* If the time is less than or equal to zero, the method will not wait
* at all.
*
* @param timeout the maximum time to wait for a permit
* @param unit the time unit of the <tt>timeout</tt> argument.
* @return <tt>true</tt> if a permit was acquired and <tt>false</tt>
* if the waiting time elapsed before a permit was acquired.
*
* @throws InterruptedException if the current thread is interrupted
*
* @see Thread#interrupt
*
*/
public boolean tryAcquire(long timeout, TimeUnit unit)
throws InterruptedException {
return impl.attempt(unit.toNanos(timeout));
}
/**
* Releases a permit, returning it to the semaphore.
* <p>Releases a permit, increasing the number of available permits
* by one.
* If any threads are trying to acquire a permit, then one
* is selected and given the permit that was just released.
* That thread is (re)enabled for thread scheduling purposes.
* <p>There is no requirement that a thread that releases a permit must
* have acquired that permit by calling {@link #acquire}.
* Correct usage of a semaphore is established by programming convention
* in the application.
*/
public void release() {
impl.release(1);
}
// /**
// * Acquires the given number of permits from this semaphore,
// * blocking until all are available,
// * or the thread is {@link Thread#interrupt interrupted}.
// *
// * <p>Acquires the given number of permits, if they are available,
// * and returns immediately,
// * reducing the number of available permits by the given amount.
// *
// * <p>If insufficient permits are available then the current thread becomes
// * disabled for thread scheduling purposes and lies dormant until
// * one of two things happens:
// * <ul>
// * <li>Some other thread invokes one of the {@link #release() release}
// * methods for this semaphore, the current thread is next to be assigned
// * permits and the number of available permits satisfies this request; or
// * <li>Some other thread {@link Thread#interrupt interrupts} the current
// * thread.
// * </ul>
// *
// * <p>If the current thread:
// * <ul>
// * <li>has its interrupted status set on entry to this method; or
// * <li>is {@link Thread#interrupt interrupted} while waiting
// * for a permit,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?