• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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          */
lock()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         // Android-removed: @ReservedStackAccess from OpenJDK 9, not available on Android.
131         // @ReservedStackAccess
nonfairTryAcquire(int acquires)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         // Android-removed: @ReservedStackAccess from OpenJDK 9, not available on Android.
152         // @ReservedStackAccess
tryRelease(int releases)153         protected final boolean tryRelease(int releases) {
154             int c = getState() - releases;
155             if (Thread.currentThread() != getExclusiveOwnerThread())
156                 throw new IllegalMonitorStateException();
157             boolean free = false;
158             if (c == 0) {
159                 free = true;
160                 setExclusiveOwnerThread(null);
161             }
162             setState(c);
163             return free;
164         }
165 
isHeldExclusively()166         protected final boolean isHeldExclusively() {
167             // While we must in general read state before owner,
168             // we don't need to do so to check if current thread is owner
169             return getExclusiveOwnerThread() == Thread.currentThread();
170         }
171 
newCondition()172         final ConditionObject newCondition() {
173             return new ConditionObject();
174         }
175 
176         // Methods relayed from outer class
177 
getOwner()178         final Thread getOwner() {
179             return getState() == 0 ? null : getExclusiveOwnerThread();
180         }
181 
getHoldCount()182         final int getHoldCount() {
183             return isHeldExclusively() ? getState() : 0;
184         }
185 
isLocked()186         final boolean isLocked() {
187             return getState() != 0;
188         }
189 
190         /**
191          * Reconstitutes the instance from a stream (that is, deserializes it).
192          */
readObject(java.io.ObjectInputStream s)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         // Android-removed: @ReservedStackAccess from OpenJDK 9, not available on Android.
211         // @ReservedStackAccess
lock()212         final void lock() {
213             if (compareAndSetState(0, 1))
214                 setExclusiveOwnerThread(Thread.currentThread());
215             else
216                 acquire(1);
217         }
218 
tryAcquire(int acquires)219         protected final boolean tryAcquire(int acquires) {
220             return nonfairTryAcquire(acquires);
221         }
222     }
223 
224     /**
225      * Sync object for fair locks
226      */
227     static final class FairSync extends Sync {
228         private static final long serialVersionUID = -3000897897090466540L;
229 
lock()230         final void lock() {
231             acquire(1);
232         }
233 
234         /**
235          * Fair version of tryAcquire.  Don't grant access unless
236          * recursive call or no waiters or is first.
237          */
238         // Android-removed: @ReservedStackAccess from OpenJDK 9, not available on Android.
239         // @ReservedStackAccess
tryAcquire(int acquires)240         protected final boolean tryAcquire(int acquires) {
241             final Thread current = Thread.currentThread();
242             int c = getState();
243             if (c == 0) {
244                 if (!hasQueuedPredecessors() &&
245                     compareAndSetState(0, acquires)) {
246                     setExclusiveOwnerThread(current);
247                     return true;
248                 }
249             }
250             else if (current == getExclusiveOwnerThread()) {
251                 int nextc = c + acquires;
252                 if (nextc < 0)
253                     throw new Error("Maximum lock count exceeded");
254                 setState(nextc);
255                 return true;
256             }
257             return false;
258         }
259     }
260 
261     /**
262      * Creates an instance of {@code ReentrantLock}.
263      * This is equivalent to using {@code ReentrantLock(false)}.
264      */
ReentrantLock()265     public ReentrantLock() {
266         sync = new NonfairSync();
267     }
268 
269     /**
270      * Creates an instance of {@code ReentrantLock} with the
271      * given fairness policy.
272      *
273      * @param fair {@code true} if this lock should use a fair ordering policy
274      */
ReentrantLock(boolean fair)275     public ReentrantLock(boolean fair) {
276         sync = fair ? new FairSync() : new NonfairSync();
277     }
278 
279     /**
280      * Acquires the lock.
281      *
282      * <p>Acquires the lock if it is not held by another thread and returns
283      * immediately, setting the lock hold count to one.
284      *
285      * <p>If the current thread already holds the lock then the hold
286      * count is incremented by one and the method returns immediately.
287      *
288      * <p>If the lock is held by another thread then the
289      * current thread becomes disabled for thread scheduling
290      * purposes and lies dormant until the lock has been acquired,
291      * at which time the lock hold count is set to one.
292      */
lock()293     public void lock() {
294         sync.lock();
295     }
296 
297     /**
298      * Acquires the lock unless the current thread is
299      * {@linkplain Thread#interrupt interrupted}.
300      *
301      * <p>Acquires the lock if it is not held by another thread and returns
302      * immediately, setting the lock hold count to one.
303      *
304      * <p>If the current thread already holds this lock then the hold count
305      * is incremented by one and the method returns immediately.
306      *
307      * <p>If the lock is held by another thread then the
308      * current thread becomes disabled for thread scheduling
309      * purposes and lies dormant until one of two things happens:
310      *
311      * <ul>
312      *
313      * <li>The lock is acquired by the current thread; or
314      *
315      * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
316      * current thread.
317      *
318      * </ul>
319      *
320      * <p>If the lock is acquired by the current thread then the lock hold
321      * count is set to one.
322      *
323      * <p>If the current thread:
324      *
325      * <ul>
326      *
327      * <li>has its interrupted status set on entry to this method; or
328      *
329      * <li>is {@linkplain Thread#interrupt interrupted} while acquiring
330      * the lock,
331      *
332      * </ul>
333      *
334      * then {@link InterruptedException} is thrown and the current thread's
335      * interrupted status is cleared.
336      *
337      * <p>In this implementation, as this method is an explicit
338      * interruption point, preference is given to responding to the
339      * interrupt over normal or reentrant acquisition of the lock.
340      *
341      * @throws InterruptedException if the current thread is interrupted
342      */
lockInterruptibly()343     public void lockInterruptibly() throws InterruptedException {
344         sync.acquireInterruptibly(1);
345     }
346 
347     /**
348      * Acquires the lock only if it is not held by another thread at the time
349      * of invocation.
350      *
351      * <p>Acquires the lock if it is not held by another thread and
352      * returns immediately with the value {@code true}, setting the
353      * lock hold count to one. Even when this lock has been set to use a
354      * fair ordering policy, a call to {@code tryLock()} <em>will</em>
355      * immediately acquire the lock if it is available, whether or not
356      * other threads are currently waiting for the lock.
357      * This &quot;barging&quot; behavior can be useful in certain
358      * circumstances, even though it breaks fairness. If you want to honor
359      * the fairness setting for this lock, then use
360      * {@link #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
361      * which is almost equivalent (it also detects interruption).
362      *
363      * <p>If the current thread already holds this lock then the hold
364      * count is incremented by one and the method returns {@code true}.
365      *
366      * <p>If the lock is held by another thread then this method will return
367      * immediately with the value {@code false}.
368      *
369      * @return {@code true} if the lock was free and was acquired by the
370      *         current thread, or the lock was already held by the current
371      *         thread; and {@code false} otherwise
372      */
tryLock()373     public boolean tryLock() {
374         return sync.nonfairTryAcquire(1);
375     }
376 
377     /**
378      * Acquires the lock if it is not held by another thread within the given
379      * waiting time and the current thread has not been
380      * {@linkplain Thread#interrupt interrupted}.
381      *
382      * <p>Acquires the lock if it is not held by another thread and returns
383      * immediately with the value {@code true}, setting the lock hold count
384      * to one. If this lock has been set to use a fair ordering policy then
385      * an available lock <em>will not</em> be acquired if any other threads
386      * are waiting for the lock. This is in contrast to the {@link #tryLock()}
387      * method. If you want a timed {@code tryLock} that does permit barging on
388      * a fair lock then combine the timed and un-timed forms together:
389      *
390      * <pre> {@code
391      * if (lock.tryLock() ||
392      *     lock.tryLock(timeout, unit)) {
393      *   ...
394      * }}</pre>
395      *
396      * <p>If the current thread
397      * already holds this lock then the hold count is incremented by one and
398      * the method returns {@code true}.
399      *
400      * <p>If the lock is held by another thread then the
401      * current thread becomes disabled for thread scheduling
402      * purposes and lies dormant until one of three things happens:
403      *
404      * <ul>
405      *
406      * <li>The lock is acquired by the current thread; or
407      *
408      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
409      * the current thread; or
410      *
411      * <li>The specified waiting time elapses
412      *
413      * </ul>
414      *
415      * <p>If the lock is acquired then the value {@code true} is returned and
416      * the lock hold count is set to one.
417      *
418      * <p>If the current thread:
419      *
420      * <ul>
421      *
422      * <li>has its interrupted status set on entry to this method; or
423      *
424      * <li>is {@linkplain Thread#interrupt interrupted} while
425      * acquiring the lock,
426      *
427      * </ul>
428      * then {@link InterruptedException} is thrown and the current thread's
429      * interrupted status is cleared.
430      *
431      * <p>If the specified waiting time elapses then the value {@code false}
432      * is returned.  If the time is less than or equal to zero, the method
433      * will not wait at all.
434      *
435      * <p>In this implementation, as this method is an explicit
436      * interruption point, preference is given to responding to the
437      * interrupt over normal or reentrant acquisition of the lock, and
438      * over reporting the elapse of the waiting time.
439      *
440      * @param timeout the time to wait for the lock
441      * @param unit the time unit of the timeout argument
442      * @return {@code true} if the lock was free and was acquired by the
443      *         current thread, or the lock was already held by the current
444      *         thread; and {@code false} if the waiting time elapsed before
445      *         the lock could be acquired
446      * @throws InterruptedException if the current thread is interrupted
447      * @throws NullPointerException if the time unit is null
448      */
tryLock(long timeout, TimeUnit unit)449     public boolean tryLock(long timeout, TimeUnit unit)
450             throws InterruptedException {
451         return sync.tryAcquireNanos(1, unit.toNanos(timeout));
452     }
453 
454     /**
455      * Attempts to release this lock.
456      *
457      * <p>If the current thread is the holder of this lock then the hold
458      * count is decremented.  If the hold count is now zero then the lock
459      * is released.  If the current thread is not the holder of this
460      * lock then {@link IllegalMonitorStateException} is thrown.
461      *
462      * @throws IllegalMonitorStateException if the current thread does not
463      *         hold this lock
464      */
unlock()465     public void unlock() {
466         sync.release(1);
467     }
468 
469     /**
470      * Returns a {@link Condition} instance for use with this
471      * {@link Lock} instance.
472      *
473      * <p>The returned {@link Condition} instance supports the same
474      * usages as do the {@link Object} monitor methods ({@link
475      * Object#wait() wait}, {@link Object#notify notify}, and {@link
476      * Object#notifyAll notifyAll}) when used with the built-in
477      * monitor lock.
478      *
479      * <ul>
480      *
481      * <li>If this lock is not held when any of the {@link Condition}
482      * {@linkplain Condition#await() waiting} or {@linkplain
483      * Condition#signal signalling} methods are called, then an {@link
484      * IllegalMonitorStateException} is thrown.
485      *
486      * <li>When the condition {@linkplain Condition#await() waiting}
487      * methods are called the lock is released and, before they
488      * return, the lock is reacquired and the lock hold count restored
489      * to what it was when the method was called.
490      *
491      * <li>If a thread is {@linkplain Thread#interrupt interrupted}
492      * while waiting then the wait will terminate, an {@link
493      * InterruptedException} will be thrown, and the thread's
494      * interrupted status will be cleared.
495      *
496      * <li>Waiting threads are signalled in FIFO order.
497      *
498      * <li>The ordering of lock reacquisition for threads returning
499      * from waiting methods is the same as for threads initially
500      * acquiring the lock, which is in the default case not specified,
501      * but for <em>fair</em> locks favors those threads that have been
502      * waiting the longest.
503      *
504      * </ul>
505      *
506      * @return the Condition object
507      */
newCondition()508     public Condition newCondition() {
509         return sync.newCondition();
510     }
511 
512     /**
513      * Queries the number of holds on this lock by the current thread.
514      *
515      * <p>A thread has a hold on a lock for each lock action that is not
516      * matched by an unlock action.
517      *
518      * <p>The hold count information is typically only used for testing and
519      * debugging purposes. For example, if a certain section of code should
520      * not be entered with the lock already held then we can assert that
521      * fact:
522      *
523      * <pre> {@code
524      * class X {
525      *   ReentrantLock lock = new ReentrantLock();
526      *   // ...
527      *   public void m() {
528      *     assert lock.getHoldCount() == 0;
529      *     lock.lock();
530      *     try {
531      *       // ... method body
532      *     } finally {
533      *       lock.unlock();
534      *     }
535      *   }
536      * }}</pre>
537      *
538      * @return the number of holds on this lock by the current thread,
539      *         or zero if this lock is not held by the current thread
540      */
getHoldCount()541     public int getHoldCount() {
542         return sync.getHoldCount();
543     }
544 
545     /**
546      * Queries if this lock is held by the current thread.
547      *
548      * <p>Analogous to the {@link Thread#holdsLock(Object)} method for
549      * built-in monitor locks, this method is typically used for
550      * debugging and testing. For example, a method that should only be
551      * called while a lock is held can assert that this is the case:
552      *
553      * <pre> {@code
554      * class X {
555      *   ReentrantLock lock = new ReentrantLock();
556      *   // ...
557      *
558      *   public void m() {
559      *       assert lock.isHeldByCurrentThread();
560      *       // ... method body
561      *   }
562      * }}</pre>
563      *
564      * <p>It can also be used to ensure that a reentrant lock is used
565      * in a non-reentrant manner, for example:
566      *
567      * <pre> {@code
568      * class X {
569      *   ReentrantLock lock = new ReentrantLock();
570      *   // ...
571      *
572      *   public void m() {
573      *       assert !lock.isHeldByCurrentThread();
574      *       lock.lock();
575      *       try {
576      *           // ... method body
577      *       } finally {
578      *           lock.unlock();
579      *       }
580      *   }
581      * }}</pre>
582      *
583      * @return {@code true} if current thread holds this lock and
584      *         {@code false} otherwise
585      */
isHeldByCurrentThread()586     public boolean isHeldByCurrentThread() {
587         return sync.isHeldExclusively();
588     }
589 
590     /**
591      * Queries if this lock is held by any thread. This method is
592      * designed for use in monitoring of the system state,
593      * not for synchronization control.
594      *
595      * @return {@code true} if any thread holds this lock and
596      *         {@code false} otherwise
597      */
isLocked()598     public boolean isLocked() {
599         return sync.isLocked();
600     }
601 
602     /**
603      * Returns {@code true} if this lock has fairness set true.
604      *
605      * @return {@code true} if this lock has fairness set true
606      */
isFair()607     public final boolean isFair() {
608         return sync instanceof FairSync;
609     }
610 
611     /**
612      * Returns the thread that currently owns this lock, or
613      * {@code null} if not owned. When this method is called by a
614      * thread that is not the owner, the return value reflects a
615      * best-effort approximation of current lock status. For example,
616      * the owner may be momentarily {@code null} even if there are
617      * threads trying to acquire the lock but have not yet done so.
618      * This method is designed to facilitate construction of
619      * subclasses that provide more extensive lock monitoring
620      * facilities.
621      *
622      * @return the owner, or {@code null} if not owned
623      */
getOwner()624     protected Thread getOwner() {
625         return sync.getOwner();
626     }
627 
628     /**
629      * Queries whether any threads are waiting to acquire this lock. Note that
630      * because cancellations may occur at any time, a {@code true}
631      * return does not guarantee that any other thread will ever
632      * acquire this lock.  This method is designed primarily for use in
633      * monitoring of the system state.
634      *
635      * @return {@code true} if there may be other threads waiting to
636      *         acquire the lock
637      */
hasQueuedThreads()638     public final boolean hasQueuedThreads() {
639         return sync.hasQueuedThreads();
640     }
641 
642     /**
643      * Queries whether the given thread is waiting to acquire this
644      * lock. Note that because cancellations may occur at any time, a
645      * {@code true} return does not guarantee that this thread
646      * will ever acquire this lock.  This method is designed primarily for use
647      * in monitoring of the system state.
648      *
649      * @param thread the thread
650      * @return {@code true} if the given thread is queued waiting for this lock
651      * @throws NullPointerException if the thread is null
652      */
hasQueuedThread(Thread thread)653     public final boolean hasQueuedThread(Thread thread) {
654         return sync.isQueued(thread);
655     }
656 
657     /**
658      * Returns an estimate of the number of threads waiting to acquire
659      * this lock.  The value is only an estimate because the number of
660      * threads may change dynamically while this method traverses
661      * internal data structures.  This method is designed for use in
662      * monitoring system state, not for synchronization control.
663      *
664      * @return the estimated number of threads waiting for this lock
665      */
getQueueLength()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      */
getQueuedThreads()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      */
hasWaiters(Condition condition)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      */
getWaitQueueLength(Condition condition)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      */
getWaitingThreads(Condition condition)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      */
toString()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 }
771