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