rt/emul/compact/src/main/java/java/util/concurrent/locks/ReentrantLock.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Sat, 19 Mar 2016 10:46:31 +0100
branchjdk7-b147
changeset 1890 212417b74b72
permissions -rw-r--r--
Bringing in all concurrent package from JDK7-b147
     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 import java.util.*;
    38 import java.util.concurrent.*;
    39 import java.util.concurrent.atomic.*;
    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() 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>
    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  * }
    90  * </pre>
    91  *
    92  * <p>In addition to implementing the {@link Lock} interface, this
    93  * class defines methods {@code isLocked} and
    94  * {@code getLockQueueLength}, as well as some associated
    95  * {@code protected} access methods that may be useful for
    96  * instrumentation and monitoring.
    97  *
    98  * <p>Serialization of this class behaves in the same way as built-in
    99  * locks: a deserialized lock is in the unlocked state, regardless of
   100  * its state when serialized.
   101  *
   102  * <p>This lock supports a maximum of 2147483647 recursive locks by
   103  * the same thread. Attempts to exceed this limit result in
   104  * {@link Error} throws from locking methods.
   105  *
   106  * @since 1.5
   107  * @author Doug Lea
   108  */
   109 public class ReentrantLock implements Lock, java.io.Serializable {
   110     private static final long serialVersionUID = 7373984872572414699L;
   111     /** Synchronizer providing all implementation mechanics */
   112     private final Sync sync;
   113 
   114     /**
   115      * Base of synchronization control for this lock. Subclassed
   116      * into fair and nonfair versions below. Uses AQS state to
   117      * represent the number of holds on the lock.
   118      */
   119     abstract static class Sync extends AbstractQueuedSynchronizer {
   120         private static final long serialVersionUID = -5179523762034025860L;
   121 
   122         /**
   123          * Performs {@link Lock#lock}. The main reason for subclassing
   124          * is to allow fast path for nonfair version.
   125          */
   126         abstract void lock();
   127 
   128         /**
   129          * Performs non-fair tryLock.  tryAcquire is
   130          * implemented in subclasses, but both need nonfair
   131          * try for trylock method.
   132          */
   133         final boolean nonfairTryAcquire(int acquires) {
   134             final Thread current = Thread.currentThread();
   135             int c = getState();
   136             if (c == 0) {
   137                 if (compareAndSetState(0, acquires)) {
   138                     setExclusiveOwnerThread(current);
   139                     return true;
   140                 }
   141             }
   142             else if (current == getExclusiveOwnerThread()) {
   143                 int nextc = c + acquires;
   144                 if (nextc < 0) // overflow
   145                     throw new Error("Maximum lock count exceeded");
   146                 setState(nextc);
   147                 return true;
   148             }
   149             return false;
   150         }
   151 
   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 this lock instance from a stream.
   191          * @param s the stream
   192          */
   193         private void readObject(java.io.ObjectInputStream s)
   194             throws java.io.IOException, ClassNotFoundException {
   195             s.defaultReadObject();
   196             setState(0); // reset to unlocked state
   197         }
   198     }
   199 
   200     /**
   201      * Sync object for non-fair locks
   202      */
   203     static final class NonfairSync extends Sync {
   204         private static final long serialVersionUID = 7316153563782823691L;
   205 
   206         /**
   207          * Performs lock.  Try immediate barge, backing up to normal
   208          * acquire on failure.
   209          */
   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         protected final boolean tryAcquire(int acquires) {
   237             final Thread current = Thread.currentThread();
   238             int c = getState();
   239             if (c == 0) {
   240                 if (!hasQueuedPredecessors() &&
   241                     compareAndSetState(0, acquires)) {
   242                     setExclusiveOwnerThread(current);
   243                     return true;
   244                 }
   245             }
   246             else if (current == getExclusiveOwnerThread()) {
   247                 int nextc = c + acquires;
   248                 if (nextc < 0)
   249                     throw new Error("Maximum lock count exceeded");
   250                 setState(nextc);
   251                 return true;
   252             }
   253             return false;
   254         }
   255     }
   256 
   257     /**
   258      * Creates an instance of {@code ReentrantLock}.
   259      * This is equivalent to using {@code ReentrantLock(false)}.
   260      */
   261     public ReentrantLock() {
   262         sync = new NonfairSync();
   263     }
   264 
   265     /**
   266      * Creates an instance of {@code ReentrantLock} with the
   267      * given fairness policy.
   268      *
   269      * @param fair {@code true} if this lock should use a fair ordering policy
   270      */
   271     public ReentrantLock(boolean fair) {
   272         sync = fair ? new FairSync() : new NonfairSync();
   273     }
   274 
   275     /**
   276      * Acquires the lock.
   277      *
   278      * <p>Acquires the lock if it is not held by another thread and returns
   279      * immediately, setting the lock hold count to one.
   280      *
   281      * <p>If the current thread already holds the lock then the hold
   282      * count is incremented by one and the method returns immediately.
   283      *
   284      * <p>If the lock is held by another thread then the
   285      * current thread becomes disabled for thread scheduling
   286      * purposes and lies dormant until the lock has been acquired,
   287      * at which time the lock hold count is set to one.
   288      */
   289     public void lock() {
   290         sync.lock();
   291     }
   292 
   293     /**
   294      * Acquires the lock unless the current thread is
   295      * {@linkplain Thread#interrupt interrupted}.
   296      *
   297      * <p>Acquires the lock if it is not held by another thread and returns
   298      * immediately, setting the lock hold count to one.
   299      *
   300      * <p>If the current thread already holds this lock then the hold count
   301      * is incremented by one and the method returns immediately.
   302      *
   303      * <p>If the lock is held by another thread then the
   304      * current thread becomes disabled for thread scheduling
   305      * purposes and lies dormant until one of two things happens:
   306      *
   307      * <ul>
   308      *
   309      * <li>The lock is acquired by the current thread; or
   310      *
   311      * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
   312      * current thread.
   313      *
   314      * </ul>
   315      *
   316      * <p>If the lock is acquired by the current thread then the lock hold
   317      * count is set to one.
   318      *
   319      * <p>If the current thread:
   320      *
   321      * <ul>
   322      *
   323      * <li>has its interrupted status set on entry to this method; or
   324      *
   325      * <li>is {@linkplain Thread#interrupt interrupted} while acquiring
   326      * the lock,
   327      *
   328      * </ul>
   329      *
   330      * then {@link InterruptedException} is thrown and the current thread's
   331      * interrupted status is cleared.
   332      *
   333      * <p>In this implementation, as this method is an explicit
   334      * interruption point, preference is given to responding to the
   335      * interrupt over normal or reentrant acquisition of the lock.
   336      *
   337      * @throws InterruptedException if the current thread is interrupted
   338      */
   339     public void lockInterruptibly() throws InterruptedException {
   340         sync.acquireInterruptibly(1);
   341     }
   342 
   343     /**
   344      * Acquires the lock only if it is not held by another thread at the time
   345      * of invocation.
   346      *
   347      * <p>Acquires the lock if it is not held by another thread and
   348      * returns immediately with the value {@code true}, setting the
   349      * lock hold count to one. Even when this lock has been set to use a
   350      * fair ordering policy, a call to {@code tryLock()} <em>will</em>
   351      * immediately acquire the lock if it is available, whether or not
   352      * other threads are currently waiting for the lock.
   353      * This &quot;barging&quot; behavior can be useful in certain
   354      * circumstances, even though it breaks fairness. If you want to honor
   355      * the fairness setting for this lock, then use
   356      * {@link #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
   357      * which is almost equivalent (it also detects interruption).
   358      *
   359      * <p> If the current thread already holds this lock then the hold
   360      * count is incremented by one and the method returns {@code true}.
   361      *
   362      * <p>If the lock is held by another thread then this method will return
   363      * immediately with the value {@code false}.
   364      *
   365      * @return {@code true} if the lock was free and was acquired by the
   366      *         current thread, or the lock was already held by the current
   367      *         thread; and {@code false} otherwise
   368      */
   369     public boolean tryLock() {
   370         return sync.nonfairTryAcquire(1);
   371     }
   372 
   373     /**
   374      * Acquires the lock if it is not held by another thread within the given
   375      * waiting time and the current thread has not been
   376      * {@linkplain Thread#interrupt interrupted}.
   377      *
   378      * <p>Acquires the lock if it is not held by another thread and returns
   379      * immediately with the value {@code true}, setting the lock hold count
   380      * to one. If this lock has been set to use a fair ordering policy then
   381      * an available lock <em>will not</em> be acquired if any other threads
   382      * are waiting for the lock. This is in contrast to the {@link #tryLock()}
   383      * method. If you want a timed {@code tryLock} that does permit barging on
   384      * a fair lock then combine the timed and un-timed forms together:
   385      *
   386      * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
   387      * </pre>
   388      *
   389      * <p>If the current thread
   390      * already holds this lock then the hold count is incremented by one and
   391      * the method returns {@code true}.
   392      *
   393      * <p>If the lock is held by another thread then the
   394      * current thread becomes disabled for thread scheduling
   395      * purposes and lies dormant until one of three things happens:
   396      *
   397      * <ul>
   398      *
   399      * <li>The lock is acquired by the current thread; or
   400      *
   401      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
   402      * the current thread; or
   403      *
   404      * <li>The specified waiting time elapses
   405      *
   406      * </ul>
   407      *
   408      * <p>If the lock is acquired then the value {@code true} is returned and
   409      * the lock hold count is set to one.
   410      *
   411      * <p>If the current thread:
   412      *
   413      * <ul>
   414      *
   415      * <li>has its interrupted status set on entry to this method; or
   416      *
   417      * <li>is {@linkplain Thread#interrupt interrupted} while
   418      * acquiring the lock,
   419      *
   420      * </ul>
   421      * then {@link InterruptedException} is thrown and the current thread's
   422      * interrupted status is cleared.
   423      *
   424      * <p>If the specified waiting time elapses then the value {@code false}
   425      * is returned.  If the time is less than or equal to zero, the method
   426      * will not wait at all.
   427      *
   428      * <p>In this implementation, as this method is an explicit
   429      * interruption point, preference is given to responding to the
   430      * interrupt over normal or reentrant acquisition of the lock, and
   431      * over reporting the elapse of the waiting time.
   432      *
   433      * @param timeout the time to wait for the lock
   434      * @param unit the time unit of the timeout argument
   435      * @return {@code true} if the lock was free and was acquired by the
   436      *         current thread, or the lock was already held by the current
   437      *         thread; and {@code false} if the waiting time elapsed before
   438      *         the lock could be acquired
   439      * @throws InterruptedException if the current thread is interrupted
   440      * @throws NullPointerException if the time unit is null
   441      *
   442      */
   443     public boolean tryLock(long timeout, TimeUnit unit)
   444             throws InterruptedException {
   445         return sync.tryAcquireNanos(1, unit.toNanos(timeout));
   446     }
   447 
   448     /**
   449      * Attempts to release this lock.
   450      *
   451      * <p>If the current thread is the holder of this lock then the hold
   452      * count is decremented.  If the hold count is now zero then the lock
   453      * is released.  If the current thread is not the holder of this
   454      * lock then {@link IllegalMonitorStateException} is thrown.
   455      *
   456      * @throws IllegalMonitorStateException if the current thread does not
   457      *         hold this lock
   458      */
   459     public void unlock() {
   460         sync.release(1);
   461     }
   462 
   463     /**
   464      * Returns a {@link Condition} instance for use with this
   465      * {@link Lock} instance.
   466      *
   467      * <p>The returned {@link Condition} instance supports the same
   468      * usages as do the {@link Object} monitor methods ({@link
   469      * Object#wait() wait}, {@link Object#notify notify}, and {@link
   470      * Object#notifyAll notifyAll}) when used with the built-in
   471      * monitor lock.
   472      *
   473      * <ul>
   474      *
   475      * <li>If this lock is not held when any of the {@link Condition}
   476      * {@linkplain Condition#await() waiting} or {@linkplain
   477      * Condition#signal signalling} methods are called, then an {@link
   478      * IllegalMonitorStateException} is thrown.
   479      *
   480      * <li>When the condition {@linkplain Condition#await() waiting}
   481      * methods are called the lock is released and, before they
   482      * return, the lock is reacquired and the lock hold count restored
   483      * to what it was when the method was called.
   484      *
   485      * <li>If a thread is {@linkplain Thread#interrupt interrupted}
   486      * while waiting then the wait will terminate, an {@link
   487      * InterruptedException} will be thrown, and the thread's
   488      * interrupted status will be cleared.
   489      *
   490      * <li> Waiting threads are signalled in FIFO order.
   491      *
   492      * <li>The ordering of lock reacquisition for threads returning
   493      * from waiting methods is the same as for threads initially
   494      * acquiring the lock, which is in the default case not specified,
   495      * but for <em>fair</em> locks favors those threads that have been
   496      * waiting the longest.
   497      *
   498      * </ul>
   499      *
   500      * @return the Condition object
   501      */
   502     public Condition newCondition() {
   503         return sync.newCondition();
   504     }
   505 
   506     /**
   507      * Queries the number of holds on this lock by the current thread.
   508      *
   509      * <p>A thread has a hold on a lock for each lock action that is not
   510      * matched by an unlock action.
   511      *
   512      * <p>The hold count information is typically only used for testing and
   513      * debugging purposes. For example, if a certain section of code should
   514      * not be entered with the lock already held then we can assert that
   515      * fact:
   516      *
   517      * <pre>
   518      * class X {
   519      *   ReentrantLock lock = new ReentrantLock();
   520      *   // ...
   521      *   public void m() {
   522      *     assert lock.getHoldCount() == 0;
   523      *     lock.lock();
   524      *     try {
   525      *       // ... method body
   526      *     } finally {
   527      *       lock.unlock();
   528      *     }
   529      *   }
   530      * }
   531      * </pre>
   532      *
   533      * @return the number of holds on this lock by the current thread,
   534      *         or zero if this lock is not held by the current thread
   535      */
   536     public int getHoldCount() {
   537         return sync.getHoldCount();
   538     }
   539 
   540     /**
   541      * Queries if this lock is held by the current thread.
   542      *
   543      * <p>Analogous to the {@link Thread#holdsLock} method for built-in
   544      * monitor locks, this method is typically used for debugging and
   545      * testing. For example, a method that should only be called while
   546      * a lock is held can assert that this is the case:
   547      *
   548      * <pre>
   549      * class X {
   550      *   ReentrantLock lock = new ReentrantLock();
   551      *   // ...
   552      *
   553      *   public void m() {
   554      *       assert lock.isHeldByCurrentThread();
   555      *       // ... method body
   556      *   }
   557      * }
   558      * </pre>
   559      *
   560      * <p>It can also be used to ensure that a reentrant lock is used
   561      * in a non-reentrant manner, for example:
   562      *
   563      * <pre>
   564      * class X {
   565      *   ReentrantLock lock = new ReentrantLock();
   566      *   // ...
   567      *
   568      *   public void m() {
   569      *       assert !lock.isHeldByCurrentThread();
   570      *       lock.lock();
   571      *       try {
   572      *           // ... method body
   573      *       } finally {
   574      *           lock.unlock();
   575      *       }
   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     /**
   641      * Queries whether the given thread is waiting to acquire this
   642      * lock. Note that because cancellations may occur at any time, a
   643      * {@code true} return does not guarantee that this thread
   644      * will ever acquire this lock.  This method is designed primarily for use
   645      * in monitoring of the system state.
   646      *
   647      * @param thread the thread
   648      * @return {@code true} if the given thread is queued waiting for this lock
   649      * @throws NullPointerException if the thread is null
   650      */
   651     public final boolean hasQueuedThread(Thread thread) {
   652         return sync.isQueued(thread);
   653     }
   654 
   655 
   656     /**
   657      * Returns an estimate of the number of threads waiting to
   658      * acquire this lock.  The value is only an estimate because the number of
   659      * threads may change dynamically while this method traverses
   660      * internal data structures.  This method is designed for use in
   661      * monitoring of the system state, not for synchronization
   662      * control.
   663      *
   664      * @return the estimated number of threads waiting for this lock
   665      */
   666     public final int getQueueLength() {
   667         return sync.getQueueLength();
   668     }
   669 
   670     /**
   671      * Returns a collection containing threads that may be waiting to
   672      * acquire this lock.  Because the actual set of threads may change
   673      * dynamically while constructing this result, the returned
   674      * collection is only a best-effort estimate.  The elements of the
   675      * returned collection are in no particular order.  This method is
   676      * designed to facilitate construction of subclasses that provide
   677      * more extensive monitoring facilities.
   678      *
   679      * @return the collection of threads
   680      */
   681     protected Collection<Thread> getQueuedThreads() {
   682         return sync.getQueuedThreads();
   683     }
   684 
   685     /**
   686      * Queries whether any threads are waiting on the given condition
   687      * associated with this lock. Note that because timeouts and
   688      * interrupts may occur at any time, a {@code true} return does
   689      * not guarantee that a future {@code signal} will awaken any
   690      * threads.  This method is designed primarily for use in
   691      * monitoring of the system state.
   692      *
   693      * @param condition the condition
   694      * @return {@code true} if there are any waiting threads
   695      * @throws IllegalMonitorStateException if this lock is not held
   696      * @throws IllegalArgumentException if the given condition is
   697      *         not associated with this lock
   698      * @throws NullPointerException if the condition is null
   699      */
   700     public boolean hasWaiters(Condition condition) {
   701         if (condition == null)
   702             throw new NullPointerException();
   703         if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
   704             throw new IllegalArgumentException("not owner");
   705         return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
   706     }
   707 
   708     /**
   709      * Returns an estimate of the number of threads waiting on the
   710      * given condition associated with this lock. Note that because
   711      * timeouts and interrupts may occur at any time, the estimate
   712      * serves only as an upper bound on the actual number of waiters.
   713      * This method is designed for use in monitoring of the system
   714      * state, not for synchronization control.
   715      *
   716      * @param condition the condition
   717      * @return the estimated number of waiting threads
   718      * @throws IllegalMonitorStateException if this lock is not held
   719      * @throws IllegalArgumentException if the given condition is
   720      *         not associated with this lock
   721      * @throws NullPointerException if the condition is null
   722      */
   723     public int getWaitQueueLength(Condition condition) {
   724         if (condition == null)
   725             throw new NullPointerException();
   726         if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
   727             throw new IllegalArgumentException("not owner");
   728         return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
   729     }
   730 
   731     /**
   732      * Returns a collection containing those threads that may be
   733      * waiting on the given condition associated with this lock.
   734      * Because the actual set of threads may change dynamically while
   735      * constructing this result, the returned collection is only a
   736      * best-effort estimate. The elements of the returned collection
   737      * are in no particular order.  This method is designed to
   738      * facilitate construction of subclasses that provide more
   739      * extensive condition monitoring facilities.
   740      *
   741      * @param condition the condition
   742      * @return the collection of threads
   743      * @throws IllegalMonitorStateException if this lock is not held
   744      * @throws IllegalArgumentException if the given condition is
   745      *         not associated with this lock
   746      * @throws NullPointerException if the condition is null
   747      */
   748     protected Collection<Thread> getWaitingThreads(Condition condition) {
   749         if (condition == null)
   750             throw new NullPointerException();
   751         if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
   752             throw new IllegalArgumentException("not owner");
   753         return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
   754     }
   755 
   756     /**
   757      * Returns a string identifying this lock, as well as its lock state.
   758      * The state, in brackets, includes either the String {@code "Unlocked"}
   759      * or the String {@code "Locked by"} followed by the
   760      * {@linkplain Thread#getName name} of the owning thread.
   761      *
   762      * @return a string identifying this lock, as well as its lock state
   763      */
   764     public String toString() {
   765         Thread o = sync.getOwner();
   766         return super.toString() + ((o == null) ?
   767                                    "[Unlocked]" :
   768                                    "[Locked by thread " + o.getName() + "]");
   769     }
   770 }