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