Source for java.util.concurrent.locks.ReentrantLock

   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/licenses/publicdomain
   5:  */
   6: 
   7: package java.util.concurrent.locks;
   8: import java.util.*;
   9: import java.util.concurrent.*;
  10: import java.util.concurrent.atomic.*;
  11: 
  12: /**
  13:  * A reentrant mutual exclusion {@link Lock} with the same basic
  14:  * behavior and semantics as the implicit monitor lock accessed using
  15:  * {@code synchronized} methods and statements, but with extended
  16:  * capabilities.
  17:  *
  18:  * <p>A {@code ReentrantLock} is <em>owned</em> by the thread last
  19:  * successfully locking, but not yet unlocking it. A thread invoking
  20:  * {@code lock} will return, successfully acquiring the lock, when
  21:  * the lock is not owned by another thread. The method will return
  22:  * immediately if the current thread already owns the lock. This can
  23:  * be checked using methods {@link #isHeldByCurrentThread}, and {@link
  24:  * #getHoldCount}.
  25:  *
  26:  * <p>The constructor for this class accepts an optional
  27:  * <em>fairness</em> parameter.  When set {@code true}, under
  28:  * contention, locks favor granting access to the longest-waiting
  29:  * thread.  Otherwise this lock does not guarantee any particular
  30:  * access order.  Programs using fair locks accessed by many threads
  31:  * may display lower overall throughput (i.e., are slower; often much
  32:  * slower) than those using the default setting, but have smaller
  33:  * variances in times to obtain locks and guarantee lack of
  34:  * starvation. Note however, that fairness of locks does not guarantee
  35:  * fairness of thread scheduling. Thus, one of many threads using a
  36:  * fair lock may obtain it multiple times in succession while other
  37:  * active threads are not progressing and not currently holding the
  38:  * lock.
  39:  * Also note that the untimed {@link #tryLock() tryLock} method does not
  40:  * honor the fairness setting. It will succeed if the lock
  41:  * is available even if other threads are waiting.
  42:  *
  43:  * <p>It is recommended practice to <em>always</em> immediately
  44:  * follow a call to {@code lock} with a {@code try} block, most
  45:  * typically in a before/after construction such as:
  46:  *
  47:  * <pre>
  48:  * class X {
  49:  *   private final ReentrantLock lock = new ReentrantLock();
  50:  *   // ...
  51:  *
  52:  *   public void m() {
  53:  *     lock.lock();  // block until condition holds
  54:  *     try {
  55:  *       // ... method body
  56:  *     } finally {
  57:  *       lock.unlock()
  58:  *     }
  59:  *   }
  60:  * }
  61:  * </pre>
  62:  *
  63:  * <p>In addition to implementing the {@link Lock} interface, this
  64:  * class defines methods {@code isLocked} and
  65:  * {@code getLockQueueLength}, as well as some associated
  66:  * {@code protected} access methods that may be useful for
  67:  * instrumentation and monitoring.
  68:  *
  69:  * <p>Serialization of this class behaves in the same way as built-in
  70:  * locks: a deserialized lock is in the unlocked state, regardless of
  71:  * its state when serialized.
  72:  *
  73:  * <p>This lock supports a maximum of 2147483647 recursive locks by
  74:  * the same thread. Attempts to exceed this limit result in
  75:  * {@link Error} throws from locking methods.
  76:  *
  77:  * @since 1.5
  78:  * @author Doug Lea
  79:  */
  80: public class ReentrantLock implements Lock, java.io.Serializable {
  81:     private static final long serialVersionUID = 7373984872572414699L;
  82:     /** Synchronizer providing all implementation mechanics */
  83:     private final Sync sync;
  84: 
  85:     /**
  86:      * Base of synchronization control for this lock. Subclassed
  87:      * into fair and nonfair versions below. Uses AQS state to
  88:      * represent the number of holds on the lock.
  89:      */
  90:     static abstract class Sync extends AbstractQueuedSynchronizer {
  91:         private static final long serialVersionUID = -5179523762034025860L;
  92: 
  93:         /**
  94:          * Performs {@link Lock#lock}. The main reason for subclassing
  95:          * is to allow fast path for nonfair version.
  96:          */
  97:         abstract void lock();
  98: 
  99:         /**
 100:          * Performs non-fair tryLock.  tryAcquire is
 101:          * implemented in subclasses, but both need nonfair
 102:          * try for trylock method.
 103:          */
 104:         final boolean nonfairTryAcquire(int acquires) {
 105:             final Thread current = Thread.currentThread();
 106:             int c = getState();
 107:             if (c == 0) {
 108:                 if (compareAndSetState(0, acquires)) {
 109:                     setExclusiveOwnerThread(current);
 110:                     return true;
 111:                 }
 112:             }
 113:             else if (current == getExclusiveOwnerThread()) {
 114:                 int nextc = c + acquires;
 115:                 if (nextc < 0) // overflow
 116:                     throw new Error("Maximum lock count exceeded");
 117:                 setState(nextc);
 118:                 return true;
 119:             }
 120:             return false;
 121:         }
 122: 
 123:         protected final boolean tryRelease(int releases) {
 124:             int c = getState() - releases;
 125:             if (Thread.currentThread() != getExclusiveOwnerThread())
 126:                 throw new IllegalMonitorStateException();
 127:             boolean free = false;
 128:             if (c == 0) {
 129:                 free = true;
 130:                 setExclusiveOwnerThread(null);
 131:             }
 132:             setState(c);
 133:             return free;
 134:         }
 135: 
 136:         protected final boolean isHeldExclusively() {
 137:             // While we must in general read state before owner,
 138:             // we don't need to do so to check if current thread is owner
 139:             return getExclusiveOwnerThread() == Thread.currentThread();
 140:         }
 141: 
 142:         final ConditionObject newCondition() {
 143:             return new ConditionObject();
 144:         }
 145: 
 146:         // Methods relayed from outer class
 147: 
 148:         final Thread getOwner() {
 149:             return getState() == 0 ? null : getExclusiveOwnerThread();
 150:         }
 151: 
 152:         final int getHoldCount() {
 153:             return isHeldExclusively() ? getState() : 0;
 154:         }
 155: 
 156:         final boolean isLocked() {
 157:             return getState() != 0;
 158:         }
 159: 
 160:         /**
 161:          * Reconstitutes this lock instance from a stream.
 162:          * @param s the stream
 163:          */
 164:         private void readObject(java.io.ObjectInputStream s)
 165:             throws java.io.IOException, ClassNotFoundException {
 166:             s.defaultReadObject();
 167:             setState(0); // reset to unlocked state
 168:         }
 169:     }
 170: 
 171:     /**
 172:      * Sync object for non-fair locks
 173:      */
 174:     final static class NonfairSync extends Sync {
 175:         private static final long serialVersionUID = 7316153563782823691L;
 176: 
 177:         /**
 178:          * Performs lock.  Try immediate barge, backing up to normal
 179:          * acquire on failure.
 180:          */
 181:         final void lock() {
 182:             if (compareAndSetState(0, 1))
 183:                 setExclusiveOwnerThread(Thread.currentThread());
 184:             else
 185:                 acquire(1);
 186:         }
 187: 
 188:         protected final boolean tryAcquire(int acquires) {
 189:             return nonfairTryAcquire(acquires);
 190:         }
 191:     }
 192: 
 193:     /**
 194:      * Sync object for fair locks
 195:      */
 196:     final static class FairSync extends Sync {
 197:         private static final long serialVersionUID = -3000897897090466540L;
 198: 
 199:         final void lock() {
 200:             acquire(1);
 201:         }
 202: 
 203:         /**
 204:          * Fair version of tryAcquire.  Don't grant access unless
 205:          * recursive call or no waiters or is first.
 206:          */
 207:         protected final boolean tryAcquire(int acquires) {
 208:             final Thread current = Thread.currentThread();
 209:             int c = getState();
 210:             if (c == 0) {
 211:                 if (isFirst(current) &&
 212:                     compareAndSetState(0, acquires)) {
 213:                     setExclusiveOwnerThread(current);
 214:                     return true;
 215:                 }
 216:             }
 217:             else if (current == getExclusiveOwnerThread()) {
 218:                 int nextc = c + acquires;
 219:                 if (nextc < 0)
 220:                     throw new Error("Maximum lock count exceeded");
 221:                 setState(nextc);
 222:                 return true;
 223:             }
 224:             return false;
 225:         }
 226:     }
 227: 
 228:     /**
 229:      * Creates an instance of {@code ReentrantLock}.
 230:      * This is equivalent to using {@code ReentrantLock(false)}.
 231:      */
 232:     public ReentrantLock() {
 233:         sync = new NonfairSync();
 234:     }
 235: 
 236:     /**
 237:      * Creates an instance of {@code ReentrantLock} with the
 238:      * given fairness policy.
 239:      *
 240:      * @param fair {@code true} if this lock should use a fair ordering policy
 241:      */
 242:     public ReentrantLock(boolean fair) {
 243:         sync = (fair)? new FairSync() : new NonfairSync();
 244:     }
 245: 
 246:     /**
 247:      * Acquires the lock.
 248:      *
 249:      * <p>Acquires the lock if it is not held by another thread and returns
 250:      * immediately, setting the lock hold count to one.
 251:      *
 252:      * <p>If the current thread already holds the lock then the hold
 253:      * count is incremented by one and the method returns immediately.
 254:      *
 255:      * <p>If the lock is held by another thread then the
 256:      * current thread becomes disabled for thread scheduling
 257:      * purposes and lies dormant until the lock has been acquired,
 258:      * at which time the lock hold count is set to one.
 259:      */
 260:     public void lock() {
 261:         sync.lock();
 262:     }
 263: 
 264:     /**
 265:      * Acquires the lock unless the current thread is
 266:      * {@linkplain Thread#interrupt interrupted}.
 267:      *
 268:      * <p>Acquires the lock if it is not held by another thread and returns
 269:      * immediately, setting the lock hold count to one.
 270:      *
 271:      * <p>If the current thread already holds this lock then the hold count
 272:      * is incremented by one and the method returns immediately.
 273:      *
 274:      * <p>If the lock is held by another thread then the
 275:      * current thread becomes disabled for thread scheduling
 276:      * purposes and lies dormant until one of two things happens:
 277:      *
 278:      * <ul>
 279:      *
 280:      * <li>The lock is acquired by the current thread; or
 281:      *
 282:      * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
 283:      * current thread.
 284:      *
 285:      * </ul>
 286:      *
 287:      * <p>If the lock is acquired by the current thread then the lock hold
 288:      * count is set to one.
 289:      *
 290:      * <p>If the current thread:
 291:      *
 292:      * <ul>
 293:      *
 294:      * <li>has its interrupted status set on entry to this method; or
 295:      *
 296:      * <li>is {@linkplain Thread#interrupt interrupted} while acquiring
 297:      * the lock,
 298:      *
 299:      * </ul>
 300:      *
 301:      * then {@link InterruptedException} is thrown and the current thread's
 302:      * interrupted status is cleared.
 303:      *
 304:      * <p>In this implementation, as this method is an explicit
 305:      * interruption point, preference is given to responding to the
 306:      * interrupt over normal or reentrant acquisition of the lock.
 307:      *
 308:      * @throws InterruptedException if the current thread is interrupted
 309:      */
 310:     public void lockInterruptibly() throws InterruptedException {
 311:         sync.acquireInterruptibly(1);
 312:     }
 313: 
 314:     /**
 315:      * Acquires the lock only if it is not held by another thread at the time
 316:      * of invocation.
 317:      *
 318:      * <p>Acquires the lock if it is not held by another thread and
 319:      * returns immediately with the value {@code true}, setting the
 320:      * lock hold count to one. Even when this lock has been set to use a
 321:      * fair ordering policy, a call to {@code tryLock()} <em>will</em>
 322:      * immediately acquire the lock if it is available, whether or not
 323:      * other threads are currently waiting for the lock.
 324:      * This &quot;barging&quot; behavior can be useful in certain
 325:      * circumstances, even though it breaks fairness. If you want to honor
 326:      * the fairness setting for this lock, then use
 327:      * {@link #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
 328:      * which is almost equivalent (it also detects interruption).
 329:      *
 330:      * <p> If the current thread already holds this lock then the hold
 331:      * count is incremented by one and the method returns {@code true}.
 332:      *
 333:      * <p>If the lock is held by another thread then this method will return
 334:      * immediately with the value {@code false}.
 335:      *
 336:      * @return {@code true} if the lock was free and was acquired by the
 337:      *         current thread, or the lock was already held by the current
 338:      *         thread; and {@code false} otherwise
 339:      */
 340:     public boolean tryLock() {
 341:         return sync.nonfairTryAcquire(1);
 342:     }
 343: 
 344:     /**
 345:      * Acquires the lock if it is not held by another thread within the given
 346:      * waiting time and the current thread has not been
 347:      * {@linkplain Thread#interrupt interrupted}.
 348:      *
 349:      * <p>Acquires the lock if it is not held by another thread and returns
 350:      * immediately with the value {@code true}, setting the lock hold count
 351:      * to one. If this lock has been set to use a fair ordering policy then
 352:      * an available lock <em>will not</em> be acquired if any other threads
 353:      * are waiting for the lock. This is in contrast to the {@link #tryLock()}
 354:      * method. If you want a timed {@code tryLock} that does permit barging on
 355:      * a fair lock then combine the timed and un-timed forms together:
 356:      *
 357:      * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
 358:      * </pre>
 359:      *
 360:      * <p>If the current thread
 361:      * already holds this lock then the hold count is incremented by one and
 362:      * the method returns {@code true}.
 363:      *
 364:      * <p>If the lock is held by another thread then the
 365:      * current thread becomes disabled for thread scheduling
 366:      * purposes and lies dormant until one of three things happens:
 367:      *
 368:      * <ul>
 369:      *
 370:      * <li>The lock is acquired by the current thread; or
 371:      *
 372:      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
 373:      * the current thread; or
 374:      *
 375:      * <li>The specified waiting time elapses
 376:      *
 377:      * </ul>
 378:      *
 379:      * <p>If the lock is acquired then the value {@code true} is returned and
 380:      * the lock hold count is set to one.
 381:      *
 382:      * <p>If the current thread:
 383:      *
 384:      * <ul>
 385:      *
 386:      * <li>has its interrupted status set on entry to this method; or
 387:      *
 388:      * <li>is {@linkplain Thread#interrupt interrupted} while
 389:      * acquiring the lock,
 390:      *
 391:      * </ul>
 392:      * then {@link InterruptedException} is thrown and the current thread's
 393:      * interrupted status is cleared.
 394:      *
 395:      * <p>If the specified waiting time elapses then the value {@code false}
 396:      * is returned.  If the time is less than or equal to zero, the method
 397:      * will not wait at all.
 398:      *
 399:      * <p>In this implementation, as this method is an explicit
 400:      * interruption point, preference is given to responding to the
 401:      * interrupt over normal or reentrant acquisition of the lock, and
 402:      * over reporting the elapse of the waiting time.
 403:      *
 404:      * @param timeout the time to wait for the lock
 405:      * @param unit the time unit of the timeout argument
 406:      * @return {@code true} if the lock was free and was acquired by the
 407:      *         current thread, or the lock was already held by the current
 408:      *         thread; and {@code false} if the waiting time elapsed before
 409:      *         the lock could be acquired
 410:      * @throws InterruptedException if the current thread is interrupted
 411:      * @throws NullPointerException if the time unit is null
 412:      *
 413:      */
 414:     public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
 415:         return sync.tryAcquireNanos(1, unit.toNanos(timeout));
 416:     }
 417: 
 418:     /**
 419:      * Attempts to release this lock.
 420:      *
 421:      * <p>If the current thread is the holder of this lock then the hold
 422:      * count is decremented.  If the hold count is now zero then the lock
 423:      * is released.  If the current thread is not the holder of this
 424:      * lock then {@link IllegalMonitorStateException} is thrown.
 425:      *
 426:      * @throws IllegalMonitorStateException if the current thread does not
 427:      *         hold this lock
 428:      */
 429:     public void unlock() {
 430:         sync.release(1);
 431:     }
 432: 
 433:     /**
 434:      * Returns a {@link Condition} instance for use with this
 435:      * {@link Lock} instance.
 436:      *
 437:      * <p>The returned {@link Condition} instance supports the same
 438:      * usages as do the {@link Object} monitor methods ({@link
 439:      * Object#wait() wait}, {@link Object#notify notify}, and {@link
 440:      * Object#notifyAll notifyAll}) when used with the built-in
 441:      * monitor lock.
 442:      *
 443:      * <ul>
 444:      *
 445:      * <li>If this lock is not held when any of the {@link Condition}
 446:      * {@linkplain Condition#await() waiting} or {@linkplain
 447:      * Condition#signal signalling} methods are called, then an {@link
 448:      * IllegalMonitorStateException} is thrown.
 449:      *
 450:      * <li>When the condition {@linkplain Condition#await() waiting}
 451:      * methods are called the lock is released and, before they
 452:      * return, the lock is reacquired and the lock hold count restored
 453:      * to what it was when the method was called.
 454:      *
 455:      * <li>If a thread is {@linkplain Thread#interrupt interrupted}
 456:      * while waiting then the wait will terminate, an {@link
 457:      * InterruptedException} will be thrown, and the thread's
 458:      * interrupted status will be cleared.
 459:      *
 460:      * <li> Waiting threads are signalled in FIFO order.
 461:      *
 462:      * <li>The ordering of lock reacquisition for threads returning
 463:      * from waiting methods is the same as for threads initially
 464:      * acquiring the lock, which is in the default case not specified,
 465:      * but for <em>fair</em> locks favors those threads that have been
 466:      * waiting the longest.
 467:      *
 468:      * </ul>
 469:      *
 470:      * @return the Condition object
 471:      */
 472:     public Condition newCondition() {
 473:         return sync.newCondition();
 474:     }
 475: 
 476:     /**
 477:      * Queries the number of holds on this lock by the current thread.
 478:      *
 479:      * <p>A thread has a hold on a lock for each lock action that is not
 480:      * matched by an unlock action.
 481:      *
 482:      * <p>The hold count information is typically only used for testing and
 483:      * debugging purposes. For example, if a certain section of code should
 484:      * not be entered with the lock already held then we can assert that
 485:      * fact:
 486:      *
 487:      * <pre>
 488:      * class X {
 489:      *   ReentrantLock lock = new ReentrantLock();
 490:      *   // ...
 491:      *   public void m() {
 492:      *     assert lock.getHoldCount() == 0;
 493:      *     lock.lock();
 494:      *     try {
 495:      *       // ... method body
 496:      *     } finally {
 497:      *       lock.unlock();
 498:      *     }
 499:      *   }
 500:      * }
 501:      * </pre>
 502:      *
 503:      * @return the number of holds on this lock by the current thread,
 504:      *         or zero if this lock is not held by the current thread
 505:      */
 506:     public int getHoldCount() {
 507:         return sync.getHoldCount();
 508:     }
 509: 
 510:     /**
 511:      * Queries if this lock is held by the current thread.
 512:      *
 513:      * <p>Analogous to the {@link Thread#holdsLock} method for built-in
 514:      * monitor locks, this method is typically used for debugging and
 515:      * testing. For example, a method that should only be called while
 516:      * a lock is held can assert that this is the case:
 517:      *
 518:      * <pre>
 519:      * class X {
 520:      *   ReentrantLock lock = new ReentrantLock();
 521:      *   // ...
 522:      *
 523:      *   public void m() {
 524:      *       assert lock.isHeldByCurrentThread();
 525:      *       // ... method body
 526:      *   }
 527:      * }
 528:      * </pre>
 529:      *
 530:      * <p>It can also be used to ensure that a reentrant lock is used
 531:      * in a non-reentrant manner, for example:
 532:      *
 533:      * <pre>
 534:      * class X {
 535:      *   ReentrantLock lock = new ReentrantLock();
 536:      *   // ...
 537:      *
 538:      *   public void m() {
 539:      *       assert !lock.isHeldByCurrentThread();
 540:      *       lock.lock();
 541:      *       try {
 542:      *           // ... method body
 543:      *       } finally {
 544:      *           lock.unlock();
 545:      *       }
 546:      *   }
 547:      * }
 548:      * </pre>
 549:      *
 550:      * @return {@code true} if current thread holds this lock and
 551:      *         {@code false} otherwise
 552:      */
 553:     public boolean isHeldByCurrentThread() {
 554:         return sync.isHeldExclusively();
 555:     }
 556: 
 557:     /**
 558:      * Queries if this lock is held by any thread. This method is
 559:      * designed for use in monitoring of the system state,
 560:      * not for synchronization control.
 561:      *
 562:      * @return {@code true} if any thread holds this lock and
 563:      *         {@code false} otherwise
 564:      */
 565:     public boolean isLocked() {
 566:         return sync.isLocked();
 567:     }
 568: 
 569:     /**
 570:      * Returns {@code true} if this lock has fairness set true.
 571:      *
 572:      * @return {@code true} if this lock has fairness set true
 573:      */
 574:     public final boolean isFair() {
 575:         return sync instanceof FairSync;
 576:     }
 577: 
 578:     /**
 579:      * Returns the thread that currently owns this lock, or
 580:      * {@code null} if not owned. When this method is called by a
 581:      * thread that is not the owner, the return value reflects a
 582:      * best-effort approximation of current lock status. For example,
 583:      * the owner may be momentarily {@code null} even if there are
 584:      * threads trying to acquire the lock but have not yet done so.
 585:      * This method is designed to facilitate construction of
 586:      * subclasses that provide more extensive lock monitoring
 587:      * facilities.
 588:      *
 589:      * @return the owner, or {@code null} if not owned
 590:      */
 591:     protected Thread getOwner() {
 592:         return sync.getOwner();
 593:     }
 594: 
 595:     /**
 596:      * Queries whether any threads are waiting to acquire this lock. Note that
 597:      * because cancellations may occur at any time, a {@code true}
 598:      * return does not guarantee that any other thread will ever
 599:      * acquire this lock.  This method is designed primarily for use in
 600:      * monitoring of the system state.
 601:      *
 602:      * @return {@code true} if there may be other threads waiting to
 603:      *         acquire the lock
 604:      */
 605:     public final boolean hasQueuedThreads() {
 606:         return sync.hasQueuedThreads();
 607:     }
 608: 
 609: 
 610:     /**
 611:      * Queries whether the given thread is waiting to acquire this
 612:      * lock. Note that because cancellations may occur at any time, a
 613:      * {@code true} return does not guarantee that this thread
 614:      * will ever acquire this lock.  This method is designed primarily for use
 615:      * in monitoring of the system state.
 616:      *
 617:      * @param thread the thread
 618:      * @return {@code true} if the given thread is queued waiting for this lock
 619:      * @throws NullPointerException if the thread is null
 620:      */
 621:     public final boolean hasQueuedThread(Thread thread) {
 622:         return sync.isQueued(thread);
 623:     }
 624: 
 625: 
 626:     /**
 627:      * Returns an estimate of the number of threads waiting to
 628:      * acquire this lock.  The value is only an estimate because the number of
 629:      * threads may change dynamically while this method traverses
 630:      * internal data structures.  This method is designed for use in
 631:      * monitoring of the system state, not for synchronization
 632:      * control.
 633:      *
 634:      * @return the estimated number of threads waiting for this lock
 635:      */
 636:     public final int getQueueLength() {
 637:         return sync.getQueueLength();
 638:     }
 639: 
 640:     /**
 641:      * Returns a collection containing threads that may be waiting to
 642:      * acquire this lock.  Because the actual set of threads may change
 643:      * dynamically while constructing this result, the returned
 644:      * collection is only a best-effort estimate.  The elements of the
 645:      * returned collection are in no particular order.  This method is
 646:      * designed to facilitate construction of subclasses that provide
 647:      * more extensive monitoring facilities.
 648:      *
 649:      * @return the collection of threads
 650:      */
 651:     protected Collection<Thread> getQueuedThreads() {
 652:         return sync.getQueuedThreads();
 653:     }
 654: 
 655:     /**
 656:      * Queries whether any threads are waiting on the given condition
 657:      * associated with this lock. Note that because timeouts and
 658:      * interrupts may occur at any time, a {@code true} return does
 659:      * not guarantee that a future {@code signal} will awaken any
 660:      * threads.  This method is designed primarily for use in
 661:      * monitoring of the system state.
 662:      *
 663:      * @param condition the condition
 664:      * @return {@code true} if there are any waiting threads
 665:      * @throws IllegalMonitorStateException if this lock is not held
 666:      * @throws IllegalArgumentException if the given condition is
 667:      *         not associated with this lock
 668:      * @throws NullPointerException if the condition is null
 669:      */
 670:     public boolean hasWaiters(Condition condition) {
 671:         if (condition == null)
 672:             throw new NullPointerException();
 673:         if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
 674:             throw new IllegalArgumentException("not owner");
 675:         return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
 676:     }
 677: 
 678:     /**
 679:      * Returns an estimate of the number of threads waiting on the
 680:      * given condition associated with this lock. Note that because
 681:      * timeouts and interrupts may occur at any time, the estimate
 682:      * serves only as an upper bound on the actual number of waiters.
 683:      * This method is designed for use in monitoring of the system
 684:      * state, not for synchronization control.
 685:      *
 686:      * @param condition the condition
 687:      * @return the estimated number of waiting threads
 688:      * @throws IllegalMonitorStateException if this lock is not held
 689:      * @throws IllegalArgumentException if the given condition is
 690:      *         not associated with this lock
 691:      * @throws NullPointerException if the condition is null
 692:      */
 693:     public int getWaitQueueLength(Condition condition) {
 694:         if (condition == null)
 695:             throw new NullPointerException();
 696:         if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
 697:             throw new IllegalArgumentException("not owner");
 698:         return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
 699:     }
 700: 
 701:     /**
 702:      * Returns a collection containing those threads that may be
 703:      * waiting on the given condition associated with this lock.
 704:      * Because the actual set of threads may change dynamically while
 705:      * constructing this result, the returned collection is only a
 706:      * best-effort estimate. The elements of the returned collection
 707:      * are in no particular order.  This method is designed to
 708:      * facilitate construction of subclasses that provide more
 709:      * extensive condition monitoring facilities.
 710:      *
 711:      * @param condition the condition
 712:      * @return the collection of threads
 713:      * @throws IllegalMonitorStateException if this lock is not held
 714:      * @throws IllegalArgumentException if the given condition is
 715:      *         not associated with this lock
 716:      * @throws NullPointerException if the condition is null
 717:      */
 718:     protected Collection<Thread> getWaitingThreads(Condition condition) {
 719:         if (condition == null)
 720:             throw new NullPointerException();
 721:         if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
 722:             throw new IllegalArgumentException("not owner");
 723:         return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
 724:     }
 725: 
 726:     /**
 727:      * Returns a string identifying this lock, as well as its lock state.
 728:      * The state, in brackets, includes either the String {@code "Unlocked"}
 729:      * or the String {@code "Locked by"} followed by the
 730:      * {@linkplain Thread#getName name} of the owning thread.
 731:      *
 732:      * @return a string identifying this lock, as well as its lock state
 733:      */
 734:     public String toString() {
 735:         Thread o = sync.getOwner();
 736:         return super.toString() + ((o == null) ?
 737:                                    "[Unlocked]" :
 738:                                    "[Locked by thread " + o.getName() + "]");
 739:     }
 740: }