ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/Semaphore.java
Revision: 1.47
Committed: Fri Sep 2 01:03:08 2005 UTC (18 years, 9 months ago) by brian
Branch: MAIN
Changes since 1.46: +6 -0 lines
Log Message:
Happens-before markup

File Contents

# User Rev Content
1 dl 1.2 /*
2     * Written by Doug Lea with assistance from members of JCP JSR-166
3 dl 1.24 * Expert Group and released to the public domain, as explained at
4     * http://creativecommons.org/licenses/publicdomain
5 dl 1.2 */
6    
7 tim 1.1 package java.util.concurrent;
8 dl 1.16 import java.util.*;
9 dl 1.5 import java.util.concurrent.locks.*;
10 dl 1.16 import java.util.concurrent.atomic.*;
11 tim 1.1
12     /**
13     * A counting semaphore. Conceptually, a semaphore maintains a set of
14     * permits. Each {@link #acquire} blocks if necessary until a permit is
15     * available, and then takes it. Each {@link #release} adds a permit,
16     * potentially releasing a blocking acquirer.
17     * However, no actual permit objects are used; the <tt>Semaphore</tt> just
18     * keeps a count of the number available and acts accordingly.
19     *
20 dl 1.16 * <p>Semaphores are often used to restrict the number of threads than can
21 tim 1.1 * access some (physical or logical) resource. For example, here is
22     * a class that uses a semaphore to control access to a pool of items:
23     * <pre>
24     * class Pool {
25 dl 1.44 * private static final int MAX_AVAILABLE = 100;
26 dl 1.16 * private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);
27 tim 1.1 *
28     * public Object getItem() throws InterruptedException {
29     * available.acquire();
30     * return getNextAvailableItem();
31     * }
32     *
33     * public void putItem(Object x) {
34     * if (markAsUnused(x))
35     * available.release();
36     * }
37     *
38     * // Not a particularly efficient data structure; just for demo
39     *
40     * protected Object[] items = ... whatever kinds of items being managed
41     * protected boolean[] used = new boolean[MAX_AVAILABLE];
42     *
43     * protected synchronized Object getNextAvailableItem() {
44     * for (int i = 0; i < MAX_AVAILABLE; ++i) {
45     * if (!used[i]) {
46     * used[i] = true;
47     * return items[i];
48     * }
49     * }
50     * return null; // not reached
51     * }
52     *
53     * protected synchronized boolean markAsUnused(Object item) {
54     * for (int i = 0; i < MAX_AVAILABLE; ++i) {
55     * if (item == items[i]) {
56     * if (used[i]) {
57     * used[i] = false;
58     * return true;
59 tim 1.8 * } else
60 tim 1.1 * return false;
61     * }
62     * }
63     * return false;
64     * }
65     *
66     * }
67     * </pre>
68     *
69 dl 1.16 * <p>Before obtaining an item each thread must acquire a permit from
70     * the semaphore, guaranteeing that an item is available for use. When
71     * the thread has finished with the item it is returned back to the
72     * pool and a permit is returned to the semaphore, allowing another
73     * thread to acquire that item. Note that no synchronization lock is
74     * held when {@link #acquire} is called as that would prevent an item
75     * from being returned to the pool. The semaphore encapsulates the
76     * synchronization needed to restrict access to the pool, separately
77     * from any synchronization needed to maintain the consistency of the
78     * pool itself.
79     *
80     * <p>A semaphore initialized to one, and which is used such that it
81     * only has at most one permit available, can serve as a mutual
82     * exclusion lock. This is more commonly known as a <em>binary
83     * semaphore</em>, because it only has two states: one permit
84     * available, or zero permits available. When used in this way, the
85     * binary semaphore has the property (unlike many {@link Lock}
86 dl 1.18 * implementations), that the &quot;lock&quot; can be released by a
87 dl 1.16 * thread other than the owner (as semaphores have no notion of
88     * ownership). This can be useful in some specialized contexts, such
89     * as deadlock recovery.
90     *
91 dl 1.36 * <p> The constructor for this class optionally accepts a
92     * <em>fairness</em> parameter. When set false, this class makes no
93     * guarantees about the order in which threads acquire permits. In
94     * particular, <em>barging</em> is permitted, that is, a thread
95     * invoking {@link #acquire} can be allocated a permit ahead of a
96 dl 1.43 * thread that has been waiting - logically the new thread places itself at
97     * the head of the queue of waiting threads. When fairness is set true, the
98 dl 1.36 * semaphore guarantees that threads invoking any of the {@link
99 dl 1.43 * #acquire() acquire} methods are selected to obtain permits in the order in
100 dl 1.36 * which their invocation of those methods was processed
101     * (first-in-first-out; FIFO). Note that FIFO ordering necessarily
102     * applies to specific internal points of execution within these
103     * methods. So, it is possible for one thread to invoke
104     * <tt>acquire</tt> before another, but reach the ordering point after
105     * the other, and similarly upon return from the method.
106 jsr166 1.45 * Also note that the untimed {@link #tryAcquire() tryAcquire} methods do not
107 dl 1.43 * honor the fairness setting, but will take any permits that are
108     * available.
109 dl 1.16 *
110     * <p>Generally, semaphores used to control resource access should be
111     * initialized as fair, to ensure that no thread is starved out from
112     * accessing a resource. When using semaphores for other kinds of
113     * synchronization control, the throughput advantages of non-fair
114     * ordering often outweigh fairness considerations.
115     *
116     * <p>This class also provides convenience methods to {@link
117     * #acquire(int) acquire} and {@link #release(int) release} multiple
118     * permits at a time. Beware of the increased risk of indefinite
119 dl 1.19 * postponement when these methods are used without fairness set true.
120 tim 1.1 *
121 brian 1.47 * <p> Memory visibility effects: Actions in a thread prior to calling
122     * a "release" method such as <tt>release()</tt> <a
123     * href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
124     * actions following a successful "acquire" method such as
125     * <tt>acquire()</tt> in another thread.
126     *
127 tim 1.1 * @since 1.5
128 dl 1.4 * @author Doug Lea
129 tim 1.1 *
130     */
131 dl 1.16
132 dl 1.23 public class Semaphore implements java.io.Serializable {
133 dl 1.16 private static final long serialVersionUID = -3222578661600680210L;
134 dl 1.25 /** All mechanics via AbstractQueuedSynchronizer subclass */
135 dl 1.23 private final Sync sync;
136    
137 dl 1.25 /**
138 dl 1.34 * Synchronization implementation for semaphore. Uses AQS state
139     * to represent permits. Subclassed into fair and nonfair
140     * versions.
141 dl 1.25 */
142 dl 1.34 abstract static class Sync extends AbstractQueuedSynchronizer {
143 dl 1.46 private static final long serialVersionUID = 1192457210091910933L;
144    
145 dl 1.34 Sync(int permits) {
146 dl 1.29 setState(permits);
147 dl 1.23 }
148 jsr166 1.45
149 dl 1.34 final int getPermits() {
150 dl 1.29 return getState();
151     }
152    
153 dl 1.34 final int nonfairTryAcquireShared(int acquires) {
154 dl 1.23 for (;;) {
155 dl 1.29 int available = getState();
156 dl 1.23 int remaining = available - acquires;
157     if (remaining < 0 ||
158 dl 1.29 compareAndSetState(available, remaining))
159 dl 1.23 return remaining;
160     }
161     }
162 jsr166 1.45
163 dl 1.34 protected final boolean tryReleaseShared(int releases) {
164 dl 1.23 for (;;) {
165 dl 1.29 int p = getState();
166 jsr166 1.45 if (compareAndSetState(p, p + releases))
167 dl 1.23 return true;
168     }
169     }
170 dl 1.29
171 dl 1.34 final void reducePermits(int reductions) {
172 dl 1.29 for (;;) {
173     int current = getState();
174     int next = current - reductions;
175     if (compareAndSetState(current, next))
176     return;
177     }
178     }
179 dl 1.31
180 dl 1.34 final int drainPermits() {
181 dl 1.31 for (;;) {
182     int current = getState();
183     if (current == 0 || compareAndSetState(current, 0))
184     return current;
185     }
186     }
187 dl 1.23 }
188 dl 1.16
189 tim 1.1 /**
190 dl 1.34 * NonFair version
191     */
192     final static class NonfairSync extends Sync {
193 dl 1.46 private static final long serialVersionUID = -2694183684443567898L;
194    
195 dl 1.34 NonfairSync(int permits) {
196     super(permits);
197     }
198 jsr166 1.45
199 dl 1.34 protected int tryAcquireShared(int acquires) {
200     return nonfairTryAcquireShared(acquires);
201     }
202     }
203    
204     /**
205     * Fair version
206     */
207     final static class FairSync extends Sync {
208 dl 1.46 private static final long serialVersionUID = 2014338818796000944L;
209    
210 dl 1.34 FairSync(int permits) {
211     super(permits);
212     }
213 jsr166 1.45
214 dl 1.34 protected int tryAcquireShared(int acquires) {
215     Thread current = Thread.currentThread();
216     for (;;) {
217 dl 1.35 Thread first = getFirstQueuedThread();
218     if (first != null && first != current)
219 dl 1.34 return -1;
220     int available = getState();
221     int remaining = available - acquires;
222     if (remaining < 0 ||
223     compareAndSetState(available, remaining))
224     return remaining;
225     }
226     }
227     }
228    
229     /**
230 dl 1.41 * Creates a <tt>Semaphore</tt> with the given number of
231 dl 1.36 * permits and nonfair fairness setting.
232     * @param permits the initial number of permits available. This
233     * value may be negative, in which case releases must
234     * occur before any acquires will be granted.
235     */
236 jsr166 1.45 public Semaphore(int permits) {
237 dl 1.36 sync = new NonfairSync(permits);
238     }
239    
240     /**
241 dl 1.41 * Creates a <tt>Semaphore</tt> with the given number of
242 dl 1.19 * permits and the given fairness setting.
243 dl 1.16 * @param permits the initial number of permits available. This
244     * value may be negative, in which case releases must
245     * occur before any acquires will be granted.
246     * @param fair true if this semaphore will guarantee first-in
247     * first-out granting of permits under contention, else false.
248 tim 1.1 */
249 jsr166 1.45 public Semaphore(int permits, boolean fair) {
250 dl 1.34 sync = (fair)? new FairSync(permits) : new NonfairSync(permits);
251 tim 1.1 }
252    
253     /**
254     * Acquires a permit from this semaphore, blocking until one is
255     * available, or the thread is {@link Thread#interrupt interrupted}.
256     *
257     * <p>Acquires a permit, if one is available and returns immediately,
258     * reducing the number of available permits by one.
259     * <p>If no permit is available then the current thread becomes
260     * disabled for thread scheduling purposes and lies dormant until
261     * one of two things happens:
262     * <ul>
263     * <li>Some other thread invokes the {@link #release} method for this
264 dl 1.16 * semaphore and the current thread is next to be assigned a permit; or
265 tim 1.1 * <li>Some other thread {@link Thread#interrupt interrupts} the current
266     * thread.
267     * </ul>
268     *
269     * <p>If the current thread:
270     * <ul>
271     * <li>has its interrupted status set on entry to this method; or
272     * <li>is {@link Thread#interrupt interrupted} while waiting
273     * for a permit,
274     * </ul>
275     * then {@link InterruptedException} is thrown and the current thread's
276     * interrupted status is cleared.
277     *
278     * @throws InterruptedException if the current thread is interrupted
279     *
280     * @see Thread#interrupt
281     */
282 dl 1.2 public void acquire() throws InterruptedException {
283 dl 1.23 sync.acquireSharedInterruptibly(1);
284 dl 1.2 }
285 tim 1.1
286     /**
287     * Acquires a permit from this semaphore, blocking until one is
288     * available.
289     *
290     * <p>Acquires a permit, if one is available and returns immediately,
291     * reducing the number of available permits by one.
292     * <p>If no permit is available then the current thread becomes
293     * disabled for thread scheduling purposes and lies dormant until
294     * some other thread invokes the {@link #release} method for this
295 dl 1.16 * semaphore and the current thread is next to be assigned a permit.
296 tim 1.1 *
297     * <p>If the current thread
298     * is {@link Thread#interrupt interrupted} while waiting
299     * for a permit then it will continue to wait, but the time at which
300     * the thread is assigned a permit may change compared to the time it
301     * would have received the permit had no interruption occurred. When the
302     * thread does return from this method its interrupt status will be set.
303     *
304     */
305 dl 1.2 public void acquireUninterruptibly() {
306 dl 1.39 sync.acquireShared(1);
307 dl 1.2 }
308 tim 1.1
309     /**
310 jsr166 1.45 * Acquires a permit from this semaphore, only if one is available at the
311 tim 1.1 * time of invocation.
312     * <p>Acquires a permit, if one is available and returns immediately,
313     * with the value <tt>true</tt>,
314     * reducing the number of available permits by one.
315     *
316     * <p>If no permit is available then this method will return
317     * immediately with the value <tt>false</tt>.
318     *
319 dl 1.27 * <p>Even when this semaphore has been set to use a
320     * fair ordering policy, a call to <tt>tryAcquire()</tt> <em>will</em>
321     * immediately acquire a permit if one is available, whether or not
322 jsr166 1.45 * other threads are currently waiting.
323     * This &quot;barging&quot; behavior can be useful in certain
324 dl 1.27 * circumstances, even though it breaks fairness. If you want to honor
325 jsr166 1.45 * the fairness setting, then use
326 dl 1.27 * {@link #tryAcquire(long, TimeUnit) tryAcquire(0, TimeUnit.SECONDS) }
327     * which is almost equivalent (it also detects interruption).
328     *
329 tim 1.1 * @return <tt>true</tt> if a permit was acquired and <tt>false</tt>
330     * otherwise.
331     */
332     public boolean tryAcquire() {
333 dl 1.34 return sync.nonfairTryAcquireShared(1) >= 0;
334 tim 1.1 }
335    
336     /**
337 jsr166 1.45 * Acquires a permit from this semaphore, if one becomes available
338 tim 1.1 * within the given waiting time and the
339     * current thread has not been {@link Thread#interrupt interrupted}.
340     * <p>Acquires a permit, if one is available and returns immediately,
341     * with the value <tt>true</tt>,
342     * reducing the number of available permits by one.
343     * <p>If no permit is available then
344     * the current thread becomes disabled for thread scheduling
345     * purposes and lies dormant until one of three things happens:
346     * <ul>
347     * <li>Some other thread invokes the {@link #release} method for this
348 dl 1.16 * semaphore and the current thread is next to be assigned a permit; or
349 tim 1.1 * <li>Some other thread {@link Thread#interrupt interrupts} the current
350     * thread; or
351     * <li>The specified waiting time elapses.
352     * </ul>
353     * <p>If a permit is acquired then the value <tt>true</tt> is returned.
354     * <p>If the current thread:
355     * <ul>
356     * <li>has its interrupted status set on entry to this method; or
357     * <li>is {@link Thread#interrupt interrupted} while waiting to acquire
358     * a permit,
359     * </ul>
360     * then {@link InterruptedException} is thrown and the current thread's
361     * interrupted status is cleared.
362     * <p>If the specified waiting time elapses then the value <tt>false</tt>
363     * is returned.
364 jsr166 1.45 * If the time is less than or equal to zero, the method will not wait
365 dl 1.16 * at all.
366 tim 1.1 *
367     * @param timeout the maximum time to wait for a permit
368 dl 1.13 * @param unit the time unit of the <tt>timeout</tt> argument.
369 tim 1.1 * @return <tt>true</tt> if a permit was acquired and <tt>false</tt>
370     * if the waiting time elapsed before a permit was acquired.
371     *
372     * @throws InterruptedException if the current thread is interrupted
373     *
374     * @see Thread#interrupt
375     *
376     */
377 jsr166 1.45 public boolean tryAcquire(long timeout, TimeUnit unit)
378 tim 1.1 throws InterruptedException {
379 dl 1.39 return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
380 tim 1.1 }
381    
382     /**
383     * Releases a permit, returning it to the semaphore.
384     * <p>Releases a permit, increasing the number of available permits
385     * by one.
386 dl 1.43 * If any threads are trying to acquire a permit, then one
387 tim 1.1 * is selected and given the permit that was just released.
388 dl 1.43 * That thread is (re)enabled for thread scheduling purposes.
389 tim 1.1 * <p>There is no requirement that a thread that releases a permit must
390     * have acquired that permit by calling {@link #acquire}.
391     * Correct usage of a semaphore is established by programming convention
392     * in the application.
393     */
394 dl 1.2 public void release() {
395 dl 1.23 sync.releaseShared(1);
396 dl 1.16 }
397 jsr166 1.45
398 dl 1.16 /**
399 jsr166 1.45 * Acquires the given number of permits from this semaphore,
400     * blocking until all are available,
401 dl 1.16 * or the thread is {@link Thread#interrupt interrupted}.
402     *
403     * <p>Acquires the given number of permits, if they are available,
404     * and returns immediately,
405     * reducing the number of available permits by the given amount.
406     *
407     * <p>If insufficient permits are available then the current thread becomes
408     * disabled for thread scheduling purposes and lies dormant until
409     * one of two things happens:
410     * <ul>
411 jsr166 1.45 * <li>Some other thread invokes one of the {@link #release() release}
412 dl 1.16 * methods for this semaphore, the current thread is next to be assigned
413     * permits and the number of available permits satisfies this request; or
414     * <li>Some other thread {@link Thread#interrupt interrupts} the current
415     * thread.
416     * </ul>
417     *
418     * <p>If the current thread:
419     * <ul>
420     * <li>has its interrupted status set on entry to this method; or
421     * <li>is {@link Thread#interrupt interrupted} while waiting
422     * for a permit,
423     * </ul>
424     * then {@link InterruptedException} is thrown and the current thread's
425 jsr166 1.45 * interrupted status is cleared.
426     * Any permits that were to be assigned to this thread are instead
427 dl 1.43 * assigned to other threads trying to acquire permits, as if
428     * permits had been made available by a call to {@link #release()}.
429 dl 1.16 *
430     * @param permits the number of permits to acquire
431     *
432     * @throws InterruptedException if the current thread is interrupted
433     * @throws IllegalArgumentException if permits less than zero.
434     *
435     * @see Thread#interrupt
436     */
437     public void acquire(int permits) throws InterruptedException {
438     if (permits < 0) throw new IllegalArgumentException();
439 dl 1.23 sync.acquireSharedInterruptibly(permits);
440 dl 1.16 }
441    
442     /**
443 jsr166 1.45 * Acquires the given number of permits from this semaphore,
444 dl 1.16 * blocking until all are available.
445     *
446     * <p>Acquires the given number of permits, if they are available,
447     * and returns immediately,
448     * reducing the number of available permits by the given amount.
449     *
450     * <p>If insufficient permits are available then the current thread becomes
451     * disabled for thread scheduling purposes and lies dormant until
452 jsr166 1.45 * some other thread invokes one of the {@link #release() release}
453 dl 1.16 * methods for this semaphore, the current thread is next to be assigned
454     * permits and the number of available permits satisfies this request.
455     *
456     * <p>If the current thread
457     * is {@link Thread#interrupt interrupted} while waiting
458     * for permits then it will continue to wait and its position in the
459     * queue is not affected. When the
460     * thread does return from this method its interrupt status will be set.
461     *
462     * @param permits the number of permits to acquire
463     * @throws IllegalArgumentException if permits less than zero.
464     *
465     */
466     public void acquireUninterruptibly(int permits) {
467     if (permits < 0) throw new IllegalArgumentException();
468 dl 1.39 sync.acquireShared(permits);
469 dl 1.16 }
470    
471     /**
472 dl 1.40 * Acquires the given number of permits from this semaphore, only
473     * if all are available at the time of invocation.
474 dl 1.41 *
475 jsr166 1.45 * <p>Acquires the given number of permits, if they are available, and
476 dl 1.16 * returns immediately, with the value <tt>true</tt>,
477     * reducing the number of available permits by the given amount.
478     *
479     * <p>If insufficient permits are available then this method will return
480     * immediately with the value <tt>false</tt> and the number of available
481     * permits is unchanged.
482     *
483 dl 1.27 * <p>Even when this semaphore has been set to use a fair ordering
484     * policy, a call to <tt>tryAcquire</tt> <em>will</em>
485     * immediately acquire a permit if one is available, whether or
486     * not other threads are currently waiting. This
487     * &quot;barging&quot; behavior can be useful in certain
488     * circumstances, even though it breaks fairness. If you want to
489     * honor the fairness setting, then use {@link #tryAcquire(int,
490     * long, TimeUnit) tryAcquire(permits, 0, TimeUnit.SECONDS) }
491     * which is almost equivalent (it also detects interruption).
492     *
493 dl 1.16 * @param permits the number of permits to acquire
494     *
495     * @return <tt>true</tt> if the permits were acquired and <tt>false</tt>
496     * otherwise.
497     * @throws IllegalArgumentException if permits less than zero.
498     */
499     public boolean tryAcquire(int permits) {
500     if (permits < 0) throw new IllegalArgumentException();
501 dl 1.34 return sync.nonfairTryAcquireShared(permits) >= 0;
502 dl 1.16 }
503    
504     /**
505 jsr166 1.45 * Acquires the given number of permits from this semaphore, if all
506 dl 1.16 * become available within the given waiting time and the
507     * current thread has not been {@link Thread#interrupt interrupted}.
508 jsr166 1.45 * <p>Acquires the given number of permits, if they are available and
509 dl 1.16 * returns immediately, with the value <tt>true</tt>,
510     * reducing the number of available permits by the given amount.
511     * <p>If insufficient permits are available then
512     * the current thread becomes disabled for thread scheduling
513     * purposes and lies dormant until one of three things happens:
514     * <ul>
515 jsr166 1.45 * <li>Some other thread invokes one of the {@link #release() release}
516 dl 1.16 * methods for this semaphore, the current thread is next to be assigned
517     * permits and the number of available permits satisfies this request; or
518     * <li>Some other thread {@link Thread#interrupt interrupts} the current
519     * thread; or
520     * <li>The specified waiting time elapses.
521     * </ul>
522     * <p>If the permits are acquired then the value <tt>true</tt> is returned.
523     * <p>If the current thread:
524     * <ul>
525     * <li>has its interrupted status set on entry to this method; or
526     * <li>is {@link Thread#interrupt interrupted} while waiting to acquire
527     * the permits,
528     * </ul>
529     * then {@link InterruptedException} is thrown and the current thread's
530     * interrupted status is cleared.
531 jsr166 1.45 * Any permits that were to be assigned to this thread, are instead
532 dl 1.43 * assigned to other threads trying to acquire permits, as if
533     * the permits had been made available by a call to {@link #release()}.
534 dl 1.16 *
535     * <p>If the specified waiting time elapses then the value <tt>false</tt>
536     * is returned.
537     * If the time is
538     * less than or equal to zero, the method will not wait at all.
539 jsr166 1.45 * Any permits that were to be assigned to this thread, are instead
540 dl 1.43 * assigned to other threads trying to acquire permits, as if
541     * the permits had been made available by a call to {@link #release()}.
542 dl 1.16 *
543     * @param permits the number of permits to acquire
544     * @param timeout the maximum time to wait for the permits
545     * @param unit the time unit of the <tt>timeout</tt> argument.
546     * @return <tt>true</tt> if all permits were acquired and <tt>false</tt>
547     * if the waiting time elapsed before all permits were acquired.
548     *
549     * @throws InterruptedException if the current thread is interrupted
550     * @throws IllegalArgumentException if permits less than zero.
551     *
552     * @see Thread#interrupt
553     *
554     */
555     public boolean tryAcquire(int permits, long timeout, TimeUnit unit)
556     throws InterruptedException {
557     if (permits < 0) throw new IllegalArgumentException();
558 dl 1.39 return sync.tryAcquireSharedNanos(permits, unit.toNanos(timeout));
559 dl 1.16 }
560    
561     /**
562     * Releases the given number of permits, returning them to the semaphore.
563 jsr166 1.45 * <p>Releases the given number of permits, increasing the number of
564 dl 1.16 * available permits by that amount.
565 dl 1.43 * If any threads are trying to acquire permits, then one
566 dl 1.16 * is selected and given the permits that were just released.
567     * If the number of available permits satisfies that thread's request
568 dl 1.43 * then that thread is (re)enabled for thread scheduling purposes;
569     * otherwise the thread will wait until sufficient permits are available.
570     * If there are still permits available
571     * after this thread's request has been satisfied, then those permits
572     * are assigned in turn to other threads trying to acquire permits.
573 dl 1.16 *
574     * <p>There is no requirement that a thread that releases a permit must
575     * have acquired that permit by calling {@link Semaphore#acquire acquire}.
576     * Correct usage of a semaphore is established by programming convention
577     * in the application.
578     *
579     * @param permits the number of permits to release
580     * @throws IllegalArgumentException if permits less than zero.
581     */
582     public void release(int permits) {
583     if (permits < 0) throw new IllegalArgumentException();
584 dl 1.23 sync.releaseShared(permits);
585 dl 1.2 }
586 tim 1.1
587     /**
588 dl 1.41 * Returns the current number of permits available in this semaphore.
589 tim 1.1 * <p>This method is typically used for debugging and testing purposes.
590     * @return the number of permits available in this semaphore.
591     */
592 dl 1.16 public int availablePermits() {
593 dl 1.29 return sync.getPermits();
594 tim 1.1 }
595 dl 1.15
596     /**
597 jsr166 1.45 * Acquires and returns all permits that are immediately available.
598     * @return the number of permits
599 dl 1.31 */
600     public int drainPermits() {
601     return sync.drainPermits();
602     }
603    
604     /**
605 dl 1.41 * Shrinks the number of available permits by the indicated
606 dl 1.40 * reduction. This method can be useful in subclasses that use
607     * semaphores to track resources that become unavailable. This
608     * method differs from <tt>acquire</tt> in that it does not block
609     * waiting for permits to become available.
610 dl 1.15 * @param reduction the number of permits to remove
611     * @throws IllegalArgumentException if reduction is negative
612     */
613 dl 1.16 protected void reducePermits(int reduction) {
614 dl 1.15 if (reduction < 0) throw new IllegalArgumentException();
615 dl 1.29 sync.reducePermits(reduction);
616 dl 1.16 }
617    
618     /**
619 dl 1.42 * Returns true if this semaphore has fairness set true.
620 dl 1.16 * @return true if this semaphore has fairness set true.
621     */
622     public boolean isFair() {
623 dl 1.34 return sync instanceof FairSync;
624 dl 1.22 }
625    
626     /**
627 dl 1.23 * Queries whether any threads are waiting to acquire. Note that
628     * because cancellations may occur at any time, a <tt>true</tt>
629     * return does not guarantee that any other thread will ever
630     * acquire. This method is designed primarily for use in
631     * monitoring of the system state.
632     *
633     * @return true if there may be other threads waiting to acquire
634     * the lock.
635 dl 1.22 */
636 jsr166 1.45 public final boolean hasQueuedThreads() {
637 dl 1.25 return sync.hasQueuedThreads();
638 dl 1.22 }
639    
640     /**
641 dl 1.23 * Returns an estimate of the number of threads waiting to
642     * acquire. The value is only an estimate because the number of
643     * threads may change dynamically while this method traverses
644     * internal data structures. This method is designed for use in
645     * monitoring of the system state, not for synchronization
646     * control.
647     * @return the estimated number of threads waiting for this lock
648 dl 1.22 */
649 dl 1.23 public final int getQueueLength() {
650     return sync.getQueueLength();
651 dl 1.22 }
652    
653     /**
654 dl 1.23 * Returns a collection containing threads that may be waiting to
655     * acquire. Because the actual set of threads may change
656     * dynamically while constructing this result, the returned
657     * collection is only a best-effort estimate. The elements of the
658     * returned collection are in no particular order. This method is
659     * designed to facilitate construction of subclasses that provide
660     * more extensive monitoring facilities.
661     * @return the collection of threads
662 dl 1.22 */
663 dl 1.23 protected Collection<Thread> getQueuedThreads() {
664     return sync.getQueuedThreads();
665 dl 1.16 }
666 dl 1.37
667     /**
668 dl 1.40 * Returns a string identifying this semaphore, as well as its state.
669 jsr166 1.45 * The state, in brackets, includes the String
670 dl 1.38 * &quot;Permits =&quot; followed by the number of permits.
671     * @return a string identifying this semaphore, as well as its
672     * state
673 dl 1.37 */
674     public String toString() {
675     return super.toString() + "[Permits = " + sync.getPermits() + "]";
676     }
677    
678 tim 1.1 }