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