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