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