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.
7  *
8  * This code is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11  * version 2 for more details (a copy is included in the LICENSE file that
12  * accompanied this code).
13  *
14  * You should have received a copy of the GNU General Public License version
15  * 2 along with this work; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19  * or visit www.oracle.com if you need additional information or have any
20  * questions.
21  */
22 
23 /*
24  * This file is available under and governed by the GNU General Public
25  * License version 2 only, as published by the Free Software Foundation.
26  * However, the following notice accompanied the original version of this
27  * file:
28  *
29  * Written by Doug Lea with assistance from members of JCP JSR-166
30  * Expert Group and released to the public domain, as explained at
31  * http://creativecommons.org/publicdomain/zero/1.0/
32  * Other contributors include Andrew Wright, Jeffrey Hayes,
33  * Pat Fisher, Mike Judd.
34  */
35 
36 import static java.util.concurrent.TimeUnit.MILLISECONDS;
37 
38 import java.util.ArrayList;
39 import java.util.Arrays;
40 import java.util.Collection;
41 import java.util.HashSet;
42 import java.util.concurrent.Callable;
43 import java.util.concurrent.CountDownLatch;
44 import java.util.concurrent.CyclicBarrier;
45 import java.util.concurrent.ThreadLocalRandom;
46 import java.util.concurrent.atomic.AtomicBoolean;
47 import java.util.concurrent.locks.Condition;
48 import java.util.concurrent.locks.Lock;
49 import java.util.concurrent.locks.ReentrantLock;
50 
51 import junit.framework.Test;
52 import junit.framework.TestSuite;
53 
54 @SuppressWarnings("WaitNotInLoop") // we implement spurious-wakeup freedom
55 public class ReentrantLockTest extends JSR166TestCase {
main(String[] args)56     public static void main(String[] args) {
57         main(suite(), args);
58     }
suite()59     public static Test suite() {
60         return new TestSuite(ReentrantLockTest.class);
61     }
62 
63     /**
64      * A checked runnable calling lockInterruptibly
65      */
66     class InterruptibleLockRunnable extends CheckedRunnable {
67         final ReentrantLock lock;
InterruptibleLockRunnable(ReentrantLock lock)68         InterruptibleLockRunnable(ReentrantLock lock) { this.lock = lock; }
realRun()69         public void realRun() throws InterruptedException {
70             lock.lockInterruptibly();
71         }
72     }
73 
74     /**
75      * A checked runnable calling lockInterruptibly that expects to be
76      * interrupted
77      */
78     class InterruptedLockRunnable extends CheckedInterruptedRunnable {
79         final ReentrantLock lock;
InterruptedLockRunnable(ReentrantLock lock)80         InterruptedLockRunnable(ReentrantLock lock) { this.lock = lock; }
realRun()81         public void realRun() throws InterruptedException {
82             lock.lockInterruptibly();
83         }
84     }
85 
86     /**
87      * Subclass to expose protected methods
88      */
89     static class PublicReentrantLock extends ReentrantLock {
PublicReentrantLock()90         PublicReentrantLock() { super(); }
PublicReentrantLock(boolean fair)91         PublicReentrantLock(boolean fair) { super(fair); }
getOwner()92         public Thread getOwner() {
93             return super.getOwner();
94         }
getQueuedThreads()95         public Collection<Thread> getQueuedThreads() {
96             return super.getQueuedThreads();
97         }
getWaitingThreads(Condition c)98         public Collection<Thread> getWaitingThreads(Condition c) {
99             return super.getWaitingThreads(c);
100         }
101     }
102 
103     /**
104      * Releases write lock, checking that it had a hold count of 1.
105      */
releaseLock(PublicReentrantLock lock)106     void releaseLock(PublicReentrantLock lock) {
107         assertLockedByMoi(lock);
108         lock.unlock();
109         assertFalse(lock.isHeldByCurrentThread());
110         assertNotLocked(lock);
111     }
112 
113     /**
114      * Spin-waits until lock.hasQueuedThread(t) becomes true.
115      */
waitForQueuedThread(PublicReentrantLock lock, Thread t)116     void waitForQueuedThread(PublicReentrantLock lock, Thread t) {
117         long startTime = System.nanoTime();
118         while (!lock.hasQueuedThread(t)) {
119             if (millisElapsedSince(startTime) > LONG_DELAY_MS)
120                 throw new AssertionError("timed out");
121             Thread.yield();
122         }
123         assertTrue(t.isAlive());
124         assertNotSame(t, lock.getOwner());
125     }
126 
127     /**
128      * Checks that lock is not locked.
129      */
assertNotLocked(PublicReentrantLock lock)130     void assertNotLocked(PublicReentrantLock lock) {
131         assertFalse(lock.isLocked());
132         assertFalse(lock.isHeldByCurrentThread());
133         assertNull(lock.getOwner());
134         assertEquals(0, lock.getHoldCount());
135     }
136 
137     /**
138      * Checks that lock is locked by the given thread.
139      */
assertLockedBy(PublicReentrantLock lock, Thread t)140     void assertLockedBy(PublicReentrantLock lock, Thread t) {
141         assertTrue(lock.isLocked());
142         assertSame(t, lock.getOwner());
143         assertEquals(t == Thread.currentThread(),
144                      lock.isHeldByCurrentThread());
145         assertEquals(t == Thread.currentThread(),
146                      lock.getHoldCount() > 0);
147     }
148 
149     /**
150      * Checks that lock is locked by the current thread.
151      */
assertLockedByMoi(PublicReentrantLock lock)152     void assertLockedByMoi(PublicReentrantLock lock) {
153         assertLockedBy(lock, Thread.currentThread());
154     }
155 
156     /**
157      * Checks that condition c has no waiters.
158      */
assertHasNoWaiters(PublicReentrantLock lock, Condition c)159     void assertHasNoWaiters(PublicReentrantLock lock, Condition c) {
160         assertHasWaiters(lock, c, new Thread[] {});
161     }
162 
163     /**
164      * Checks that condition c has exactly the given waiter threads.
165      */
assertHasWaiters(PublicReentrantLock lock, Condition c, Thread... threads)166     void assertHasWaiters(PublicReentrantLock lock, Condition c,
167                           Thread... threads) {
168         lock.lock();
169         assertEquals(threads.length > 0, lock.hasWaiters(c));
170         assertEquals(threads.length, lock.getWaitQueueLength(c));
171         assertEquals(threads.length == 0, lock.getWaitingThreads(c).isEmpty());
172         assertEquals(threads.length, lock.getWaitingThreads(c).size());
173         assertEquals(new HashSet<Thread>(lock.getWaitingThreads(c)),
174                      new HashSet<Thread>(Arrays.asList(threads)));
175         lock.unlock();
176     }
177 
178     enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil }
179 
randomAwaitMethod()180     static AwaitMethod randomAwaitMethod() {
181         AwaitMethod[] awaitMethods = AwaitMethod.values();
182         return awaitMethods[ThreadLocalRandom.current().nextInt(awaitMethods.length)];
183     }
184 
185     /**
186      * Awaits condition "indefinitely" using the specified AwaitMethod.
187      */
await(Condition c, AwaitMethod awaitMethod)188     void await(Condition c, AwaitMethod awaitMethod)
189             throws InterruptedException {
190         long timeoutMillis = 2 * LONG_DELAY_MS;
191         switch (awaitMethod) {
192         case await:
193             c.await();
194             break;
195         case awaitTimed:
196             assertTrue(c.await(timeoutMillis, MILLISECONDS));
197             break;
198         case awaitNanos:
199             long timeoutNanos = MILLISECONDS.toNanos(timeoutMillis);
200             long nanosRemaining = c.awaitNanos(timeoutNanos);
201             assertTrue(nanosRemaining > timeoutNanos / 2);
202             assertTrue(nanosRemaining <= timeoutNanos);
203             break;
204         case awaitUntil:
205             assertTrue(c.awaitUntil(delayedDate(timeoutMillis)));
206             break;
207         default:
208             throw new AssertionError();
209         }
210     }
211 
212     /**
213      * Constructor sets given fairness, and is in unlocked state
214      */
testConstructor()215     public void testConstructor() {
216         PublicReentrantLock lock;
217 
218         lock = new PublicReentrantLock();
219         assertFalse(lock.isFair());
220         assertNotLocked(lock);
221 
222         lock = new PublicReentrantLock(true);
223         assertTrue(lock.isFair());
224         assertNotLocked(lock);
225 
226         lock = new PublicReentrantLock(false);
227         assertFalse(lock.isFair());
228         assertNotLocked(lock);
229     }
230 
231     /**
232      * locking an unlocked lock succeeds
233      */
testLock()234     public void testLock()      { testLock(false); }
testLock_fair()235     public void testLock_fair() { testLock(true); }
testLock(boolean fair)236     public void testLock(boolean fair) {
237         PublicReentrantLock lock = new PublicReentrantLock(fair);
238         lock.lock();
239         assertLockedByMoi(lock);
240         releaseLock(lock);
241     }
242 
243     /**
244      * Unlocking an unlocked lock throws IllegalMonitorStateException
245      */
testUnlock_IMSE()246     public void testUnlock_IMSE()      { testUnlock_IMSE(false); }
testUnlock_IMSE_fair()247     public void testUnlock_IMSE_fair() { testUnlock_IMSE(true); }
testUnlock_IMSE(boolean fair)248     public void testUnlock_IMSE(boolean fair) {
249         final ReentrantLock lock = new ReentrantLock(fair);
250         try {
251             lock.unlock();
252             shouldThrow();
253         } catch (IllegalMonitorStateException success) {}
254     }
255 
256     /**
257      * tryLock on an unlocked lock succeeds
258      */
testTryLock()259     public void testTryLock()      { testTryLock(false); }
testTryLock_fair()260     public void testTryLock_fair() { testTryLock(true); }
testTryLock(boolean fair)261     public void testTryLock(boolean fair) {
262         PublicReentrantLock lock = new PublicReentrantLock(fair);
263         assertTrue(lock.tryLock());
264         assertLockedByMoi(lock);
265         assertTrue(lock.tryLock());
266         assertLockedByMoi(lock);
267         lock.unlock();
268         releaseLock(lock);
269     }
270 
271     /**
272      * hasQueuedThreads reports whether there are waiting threads
273      */
testHasQueuedThreads()274     public void testHasQueuedThreads()      { testHasQueuedThreads(false); }
testHasQueuedThreads_fair()275     public void testHasQueuedThreads_fair() { testHasQueuedThreads(true); }
testHasQueuedThreads(boolean fair)276     public void testHasQueuedThreads(boolean fair) {
277         final PublicReentrantLock lock = new PublicReentrantLock(fair);
278         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
279         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
280         assertFalse(lock.hasQueuedThreads());
281         lock.lock();
282         assertFalse(lock.hasQueuedThreads());
283         t1.start();
284         waitForQueuedThread(lock, t1);
285         assertTrue(lock.hasQueuedThreads());
286         t2.start();
287         waitForQueuedThread(lock, t2);
288         assertTrue(lock.hasQueuedThreads());
289         t1.interrupt();
290         awaitTermination(t1);
291         assertTrue(lock.hasQueuedThreads());
292         lock.unlock();
293         awaitTermination(t2);
294         assertFalse(lock.hasQueuedThreads());
295     }
296 
297     /**
298      * getQueueLength reports number of waiting threads
299      */
testGetQueueLength()300     public void testGetQueueLength()      { testGetQueueLength(false); }
testGetQueueLength_fair()301     public void testGetQueueLength_fair() { testGetQueueLength(true); }
testGetQueueLength(boolean fair)302     public void testGetQueueLength(boolean fair) {
303         final PublicReentrantLock lock = new PublicReentrantLock(fair);
304         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
305         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
306         assertEquals(0, lock.getQueueLength());
307         lock.lock();
308         t1.start();
309         waitForQueuedThread(lock, t1);
310         assertEquals(1, lock.getQueueLength());
311         t2.start();
312         waitForQueuedThread(lock, t2);
313         assertEquals(2, lock.getQueueLength());
314         t1.interrupt();
315         awaitTermination(t1);
316         assertEquals(1, lock.getQueueLength());
317         lock.unlock();
318         awaitTermination(t2);
319         assertEquals(0, lock.getQueueLength());
320     }
321 
322     /**
323      * hasQueuedThread(null) throws NPE
324      */
testHasQueuedThreadNPE()325     public void testHasQueuedThreadNPE()      { testHasQueuedThreadNPE(false); }
testHasQueuedThreadNPE_fair()326     public void testHasQueuedThreadNPE_fair() { testHasQueuedThreadNPE(true); }
testHasQueuedThreadNPE(boolean fair)327     public void testHasQueuedThreadNPE(boolean fair) {
328         final ReentrantLock lock = new ReentrantLock(fair);
329         try {
330             lock.hasQueuedThread(null);
331             shouldThrow();
332         } catch (NullPointerException success) {}
333     }
334 
335     /**
336      * hasQueuedThread reports whether a thread is queued
337      */
testHasQueuedThread()338     public void testHasQueuedThread()      { testHasQueuedThread(false); }
testHasQueuedThread_fair()339     public void testHasQueuedThread_fair() { testHasQueuedThread(true); }
testHasQueuedThread(boolean fair)340     public void testHasQueuedThread(boolean fair) {
341         final PublicReentrantLock lock = new PublicReentrantLock(fair);
342         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
343         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
344         assertFalse(lock.hasQueuedThread(t1));
345         assertFalse(lock.hasQueuedThread(t2));
346         lock.lock();
347         t1.start();
348         waitForQueuedThread(lock, t1);
349         assertTrue(lock.hasQueuedThread(t1));
350         assertFalse(lock.hasQueuedThread(t2));
351         t2.start();
352         waitForQueuedThread(lock, t2);
353         assertTrue(lock.hasQueuedThread(t1));
354         assertTrue(lock.hasQueuedThread(t2));
355         t1.interrupt();
356         awaitTermination(t1);
357         assertFalse(lock.hasQueuedThread(t1));
358         assertTrue(lock.hasQueuedThread(t2));
359         lock.unlock();
360         awaitTermination(t2);
361         assertFalse(lock.hasQueuedThread(t1));
362         assertFalse(lock.hasQueuedThread(t2));
363     }
364 
365     /**
366      * getQueuedThreads includes waiting threads
367      */
testGetQueuedThreads()368     public void testGetQueuedThreads()      { testGetQueuedThreads(false); }
testGetQueuedThreads_fair()369     public void testGetQueuedThreads_fair() { testGetQueuedThreads(true); }
testGetQueuedThreads(boolean fair)370     public void testGetQueuedThreads(boolean fair) {
371         final PublicReentrantLock lock = new PublicReentrantLock(fair);
372         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
373         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
374         assertTrue(lock.getQueuedThreads().isEmpty());
375         lock.lock();
376         assertTrue(lock.getQueuedThreads().isEmpty());
377         t1.start();
378         waitForQueuedThread(lock, t1);
379         assertEquals(1, lock.getQueuedThreads().size());
380         assertTrue(lock.getQueuedThreads().contains(t1));
381         t2.start();
382         waitForQueuedThread(lock, t2);
383         assertEquals(2, lock.getQueuedThreads().size());
384         assertTrue(lock.getQueuedThreads().contains(t1));
385         assertTrue(lock.getQueuedThreads().contains(t2));
386         t1.interrupt();
387         awaitTermination(t1);
388         assertFalse(lock.getQueuedThreads().contains(t1));
389         assertTrue(lock.getQueuedThreads().contains(t2));
390         assertEquals(1, lock.getQueuedThreads().size());
391         lock.unlock();
392         awaitTermination(t2);
393         assertTrue(lock.getQueuedThreads().isEmpty());
394     }
395 
396     /**
397      * timed tryLock is interruptible
398      */
testTryLock_Interruptible()399     public void testTryLock_Interruptible()      { testTryLock_Interruptible(false); }
testTryLock_Interruptible_fair()400     public void testTryLock_Interruptible_fair() { testTryLock_Interruptible(true); }
testTryLock_Interruptible(boolean fair)401     public void testTryLock_Interruptible(boolean fair) {
402         final PublicReentrantLock lock = new PublicReentrantLock(fair);
403         lock.lock();
404         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
405             public void realRun() throws InterruptedException {
406                 lock.tryLock(2 * LONG_DELAY_MS, MILLISECONDS);
407             }});
408 
409         waitForQueuedThread(lock, t);
410         t.interrupt();
411         awaitTermination(t);
412         releaseLock(lock);
413     }
414 
415     /**
416      * tryLock on a locked lock fails
417      */
testTryLockWhenLocked()418     public void testTryLockWhenLocked()      { testTryLockWhenLocked(false); }
testTryLockWhenLocked_fair()419     public void testTryLockWhenLocked_fair() { testTryLockWhenLocked(true); }
testTryLockWhenLocked(boolean fair)420     public void testTryLockWhenLocked(boolean fair) {
421         final PublicReentrantLock lock = new PublicReentrantLock(fair);
422         lock.lock();
423         Thread t = newStartedThread(new CheckedRunnable() {
424             public void realRun() {
425                 assertFalse(lock.tryLock());
426             }});
427 
428         awaitTermination(t);
429         releaseLock(lock);
430     }
431 
432     /**
433      * Timed tryLock on a locked lock times out
434      */
testTryLock_Timeout()435     public void testTryLock_Timeout()      { testTryLock_Timeout(false); }
testTryLock_Timeout_fair()436     public void testTryLock_Timeout_fair() { testTryLock_Timeout(true); }
testTryLock_Timeout(boolean fair)437     public void testTryLock_Timeout(boolean fair) {
438         final PublicReentrantLock lock = new PublicReentrantLock(fair);
439         final long timeoutMillis = timeoutMillis();
440         lock.lock();
441         Thread t = newStartedThread(new CheckedRunnable() {
442             public void realRun() throws InterruptedException {
443                 long startTime = System.nanoTime();
444                 assertFalse(lock.tryLock(timeoutMillis, MILLISECONDS));
445                 assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
446             }});
447 
448         awaitTermination(t);
449         releaseLock(lock);
450     }
451 
452     /**
453      * getHoldCount returns number of recursive holds
454      */
testGetHoldCount()455     public void testGetHoldCount()      { testGetHoldCount(false); }
testGetHoldCount_fair()456     public void testGetHoldCount_fair() { testGetHoldCount(true); }
testGetHoldCount(boolean fair)457     public void testGetHoldCount(boolean fair) {
458         final ReentrantLock lock = new ReentrantLock(fair);
459         for (int i = 1; i <= SIZE; i++) {
460             lock.lock();
461             assertEquals(i, lock.getHoldCount());
462         }
463         for (int i = SIZE; i > 0; i--) {
464             lock.unlock();
465             assertEquals(i - 1, lock.getHoldCount());
466         }
467     }
468 
469     /**
470      * isLocked is true when locked and false when not
471      */
testIsLocked()472     public void testIsLocked()      { testIsLocked(false); }
testIsLocked_fair()473     public void testIsLocked_fair() { testIsLocked(true); }
testIsLocked(boolean fair)474     public void testIsLocked(boolean fair) {
475         final ReentrantLock lock = new ReentrantLock(fair);
476         try {
477             assertFalse(lock.isLocked());
478             lock.lock();
479             assertTrue(lock.isLocked());
480             lock.lock();
481             assertTrue(lock.isLocked());
482             lock.unlock();
483             assertTrue(lock.isLocked());
484             lock.unlock();
485             assertFalse(lock.isLocked());
486             final CyclicBarrier barrier = new CyclicBarrier(2);
487             Thread t = newStartedThread(new CheckedRunnable() {
488                     public void realRun() throws Exception {
489                         lock.lock();
490                         assertTrue(lock.isLocked());
491                         barrier.await();
492                         barrier.await();
493                         lock.unlock();
494                     }});
495 
496             barrier.await();
497             assertTrue(lock.isLocked());
498             barrier.await();
499             awaitTermination(t);
500             assertFalse(lock.isLocked());
501         } catch (Exception fail) { threadUnexpectedException(fail); }
502     }
503 
504     /**
505      * lockInterruptibly succeeds when unlocked, else is interruptible
506      */
testLockInterruptibly()507     public void testLockInterruptibly()      { testLockInterruptibly(false); }
testLockInterruptibly_fair()508     public void testLockInterruptibly_fair() { testLockInterruptibly(true); }
testLockInterruptibly(boolean fair)509     public void testLockInterruptibly(boolean fair) {
510         final PublicReentrantLock lock = new PublicReentrantLock(fair);
511         try {
512             lock.lockInterruptibly();
513         } catch (InterruptedException fail) { threadUnexpectedException(fail); }
514         assertLockedByMoi(lock);
515         Thread t = newStartedThread(new InterruptedLockRunnable(lock));
516         waitForQueuedThread(lock, t);
517         t.interrupt();
518         assertTrue(lock.isLocked());
519         assertTrue(lock.isHeldByCurrentThread());
520         awaitTermination(t);
521         releaseLock(lock);
522     }
523 
524     /**
525      * Calling await without holding lock throws IllegalMonitorStateException
526      */
testAwait_IMSE()527     public void testAwait_IMSE()      { testAwait_IMSE(false); }
testAwait_IMSE_fair()528     public void testAwait_IMSE_fair() { testAwait_IMSE(true); }
testAwait_IMSE(boolean fair)529     public void testAwait_IMSE(boolean fair) {
530         final ReentrantLock lock = new ReentrantLock(fair);
531         final Condition c = lock.newCondition();
532         for (AwaitMethod awaitMethod : AwaitMethod.values()) {
533             long startTime = System.nanoTime();
534             try {
535                 await(c, awaitMethod);
536                 shouldThrow();
537             } catch (IllegalMonitorStateException success) {
538             } catch (InterruptedException e) { threadUnexpectedException(e); }
539             assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
540         }
541     }
542 
543     /**
544      * Calling signal without holding lock throws IllegalMonitorStateException
545      */
546     public void testSignal_IMSE()      { testSignal_IMSE(false); }
547     public void testSignal_IMSE_fair() { testSignal_IMSE(true); }
548     public void testSignal_IMSE(boolean fair) {
549         final ReentrantLock lock = new ReentrantLock(fair);
550         final Condition c = lock.newCondition();
551         try {
552             c.signal();
553             shouldThrow();
554         } catch (IllegalMonitorStateException success) {}
555     }
556 
557     /**
558      * awaitNanos without a signal times out
559      */
560     public void testAwaitNanos_Timeout()      { testAwaitNanos_Timeout(false); }
561     public void testAwaitNanos_Timeout_fair() { testAwaitNanos_Timeout(true); }
562     public void testAwaitNanos_Timeout(boolean fair) {
563         final ReentrantLock lock = new ReentrantLock(fair);
564         final Condition c = lock.newCondition();
565         final long timeoutMillis = timeoutMillis();
566         final long timeoutNanos = MILLISECONDS.toNanos(timeoutMillis);
567         lock.lock();
568         final long startTime = System.nanoTime();
569         try {
570             long nanosRemaining = c.awaitNanos(timeoutNanos);
571             assertTrue(nanosRemaining <= 0);
572         } catch (InterruptedException fail) { threadUnexpectedException(fail); }
573         assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
574         lock.unlock();
575     }
576 
577     /**
578      * timed await without a signal times out
579      */
580     public void testAwait_Timeout()      { testAwait_Timeout(false); }
581     public void testAwait_Timeout_fair() { testAwait_Timeout(true); }
582     public void testAwait_Timeout(boolean fair) {
583         final ReentrantLock lock = new ReentrantLock(fair);
584         final Condition c = lock.newCondition();
585         final long timeoutMillis = timeoutMillis();
586         lock.lock();
587         final long startTime = System.nanoTime();
588         try {
589             assertFalse(c.await(timeoutMillis, MILLISECONDS));
590         } catch (InterruptedException fail) { threadUnexpectedException(fail); }
591         assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
592         lock.unlock();
593     }
594 
595     /**
596      * awaitUntil without a signal times out
597      */
testAwaitUntil_Timeout()598     public void testAwaitUntil_Timeout()      { testAwaitUntil_Timeout(false); }
testAwaitUntil_Timeout_fair()599     public void testAwaitUntil_Timeout_fair() { testAwaitUntil_Timeout(true); }
testAwaitUntil_Timeout(boolean fair)600     public void testAwaitUntil_Timeout(boolean fair) {
601         final ReentrantLock lock = new ReentrantLock(fair);
602         final Condition c = lock.newCondition();
603         lock.lock();
604         // We shouldn't assume that nanoTime and currentTimeMillis
605         // use the same time source, so don't use nanoTime here.
606         final java.util.Date delayedDate = delayedDate(timeoutMillis());
607         try {
608             assertFalse(c.awaitUntil(delayedDate));
609         } catch (InterruptedException fail) { threadUnexpectedException(fail); }
610         assertTrue(new java.util.Date().getTime() >= delayedDate.getTime());
611         lock.unlock();
612     }
613 
614     /**
615      * await returns when signalled
616      */
testAwait()617     public void testAwait()      { testAwait(false); }
testAwait_fair()618     public void testAwait_fair() { testAwait(true); }
testAwait(boolean fair)619     public void testAwait(boolean fair) {
620         final PublicReentrantLock lock = new PublicReentrantLock(fair);
621         final Condition c = lock.newCondition();
622         final CountDownLatch locked = new CountDownLatch(1);
623         Thread t = newStartedThread(new CheckedRunnable() {
624             public void realRun() throws InterruptedException {
625                 lock.lock();
626                 locked.countDown();
627                 c.await();
628                 lock.unlock();
629             }});
630 
631         await(locked);
632         lock.lock();
633         assertHasWaiters(lock, c, t);
634         c.signal();
635         assertHasNoWaiters(lock, c);
636         assertTrue(t.isAlive());
637         lock.unlock();
638         awaitTermination(t);
639     }
640 
641     /**
642      * hasWaiters throws NPE if null
643      */
testHasWaitersNPE()644     public void testHasWaitersNPE()      { testHasWaitersNPE(false); }
testHasWaitersNPE_fair()645     public void testHasWaitersNPE_fair() { testHasWaitersNPE(true); }
testHasWaitersNPE(boolean fair)646     public void testHasWaitersNPE(boolean fair) {
647         final ReentrantLock lock = new ReentrantLock(fair);
648         try {
649             lock.hasWaiters(null);
650             shouldThrow();
651         } catch (NullPointerException success) {}
652     }
653 
654     /**
655      * getWaitQueueLength throws NPE if null
656      */
testGetWaitQueueLengthNPE()657     public void testGetWaitQueueLengthNPE()      { testGetWaitQueueLengthNPE(false); }
testGetWaitQueueLengthNPE_fair()658     public void testGetWaitQueueLengthNPE_fair() { testGetWaitQueueLengthNPE(true); }
testGetWaitQueueLengthNPE(boolean fair)659     public void testGetWaitQueueLengthNPE(boolean fair) {
660         final ReentrantLock lock = new ReentrantLock(fair);
661         try {
662             lock.getWaitQueueLength(null);
663             shouldThrow();
664         } catch (NullPointerException success) {}
665     }
666 
667     /**
668      * getWaitingThreads throws NPE if null
669      */
testGetWaitingThreadsNPE()670     public void testGetWaitingThreadsNPE()      { testGetWaitingThreadsNPE(false); }
testGetWaitingThreadsNPE_fair()671     public void testGetWaitingThreadsNPE_fair() { testGetWaitingThreadsNPE(true); }
testGetWaitingThreadsNPE(boolean fair)672     public void testGetWaitingThreadsNPE(boolean fair) {
673         final PublicReentrantLock lock = new PublicReentrantLock(fair);
674         try {
675             lock.getWaitingThreads(null);
676             shouldThrow();
677         } catch (NullPointerException success) {}
678     }
679 
680     /**
681      * hasWaiters throws IllegalArgumentException if not owned
682      */
testHasWaitersIAE()683     public void testHasWaitersIAE()      { testHasWaitersIAE(false); }
testHasWaitersIAE_fair()684     public void testHasWaitersIAE_fair() { testHasWaitersIAE(true); }
testHasWaitersIAE(boolean fair)685     public void testHasWaitersIAE(boolean fair) {
686         final ReentrantLock lock = new ReentrantLock(fair);
687         final Condition c = lock.newCondition();
688         final ReentrantLock lock2 = new ReentrantLock(fair);
689         try {
690             lock2.hasWaiters(c);
691             shouldThrow();
692         } catch (IllegalArgumentException success) {}
693     }
694 
695     /**
696      * hasWaiters throws IllegalMonitorStateException if not locked
697      */
testHasWaitersIMSE()698     public void testHasWaitersIMSE()      { testHasWaitersIMSE(false); }
testHasWaitersIMSE_fair()699     public void testHasWaitersIMSE_fair() { testHasWaitersIMSE(true); }
testHasWaitersIMSE(boolean fair)700     public void testHasWaitersIMSE(boolean fair) {
701         final ReentrantLock lock = new ReentrantLock(fair);
702         final Condition c = lock.newCondition();
703         try {
704             lock.hasWaiters(c);
705             shouldThrow();
706         } catch (IllegalMonitorStateException success) {}
707     }
708 
709     /**
710      * getWaitQueueLength throws IllegalArgumentException if not owned
711      */
testGetWaitQueueLengthIAE()712     public void testGetWaitQueueLengthIAE()      { testGetWaitQueueLengthIAE(false); }
testGetWaitQueueLengthIAE_fair()713     public void testGetWaitQueueLengthIAE_fair() { testGetWaitQueueLengthIAE(true); }
testGetWaitQueueLengthIAE(boolean fair)714     public void testGetWaitQueueLengthIAE(boolean fair) {
715         final ReentrantLock lock = new ReentrantLock(fair);
716         final Condition c = lock.newCondition();
717         final ReentrantLock lock2 = new ReentrantLock(fair);
718         try {
719             lock2.getWaitQueueLength(c);
720             shouldThrow();
721         } catch (IllegalArgumentException success) {}
722     }
723 
724     /**
725      * getWaitQueueLength throws IllegalMonitorStateException if not locked
726      */
testGetWaitQueueLengthIMSE()727     public void testGetWaitQueueLengthIMSE()      { testGetWaitQueueLengthIMSE(false); }
testGetWaitQueueLengthIMSE_fair()728     public void testGetWaitQueueLengthIMSE_fair() { testGetWaitQueueLengthIMSE(true); }
testGetWaitQueueLengthIMSE(boolean fair)729     public void testGetWaitQueueLengthIMSE(boolean fair) {
730         final ReentrantLock lock = new ReentrantLock(fair);
731         final Condition c = lock.newCondition();
732         try {
733             lock.getWaitQueueLength(c);
734             shouldThrow();
735         } catch (IllegalMonitorStateException success) {}
736     }
737 
738     /**
739      * getWaitingThreads throws IllegalArgumentException if not owned
740      */
testGetWaitingThreadsIAE()741     public void testGetWaitingThreadsIAE()      { testGetWaitingThreadsIAE(false); }
testGetWaitingThreadsIAE_fair()742     public void testGetWaitingThreadsIAE_fair() { testGetWaitingThreadsIAE(true); }
testGetWaitingThreadsIAE(boolean fair)743     public void testGetWaitingThreadsIAE(boolean fair) {
744         final PublicReentrantLock lock = new PublicReentrantLock(fair);
745         final Condition c = lock.newCondition();
746         final PublicReentrantLock lock2 = new PublicReentrantLock(fair);
747         try {
748             lock2.getWaitingThreads(c);
749             shouldThrow();
750         } catch (IllegalArgumentException success) {}
751     }
752 
753     /**
754      * getWaitingThreads throws IllegalMonitorStateException if not locked
755      */
testGetWaitingThreadsIMSE()756     public void testGetWaitingThreadsIMSE()      { testGetWaitingThreadsIMSE(false); }
testGetWaitingThreadsIMSE_fair()757     public void testGetWaitingThreadsIMSE_fair() { testGetWaitingThreadsIMSE(true); }
testGetWaitingThreadsIMSE(boolean fair)758     public void testGetWaitingThreadsIMSE(boolean fair) {
759         final PublicReentrantLock lock = new PublicReentrantLock(fair);
760         final Condition c = lock.newCondition();
761         try {
762             lock.getWaitingThreads(c);
763             shouldThrow();
764         } catch (IllegalMonitorStateException success) {}
765     }
766 
767     /**
768      * hasWaiters returns true when a thread is waiting, else false
769      */
testHasWaiters()770     public void testHasWaiters()      { testHasWaiters(false); }
testHasWaiters_fair()771     public void testHasWaiters_fair() { testHasWaiters(true); }
testHasWaiters(boolean fair)772     public void testHasWaiters(boolean fair) {
773         final PublicReentrantLock lock = new PublicReentrantLock(fair);
774         final Condition c = lock.newCondition();
775         final CountDownLatch pleaseSignal = new CountDownLatch(1);
776         Thread t = newStartedThread(new CheckedRunnable() {
777             public void realRun() throws InterruptedException {
778                 lock.lock();
779                 assertHasNoWaiters(lock, c);
780                 assertFalse(lock.hasWaiters(c));
781                 pleaseSignal.countDown();
782                 c.await();
783                 assertHasNoWaiters(lock, c);
784                 assertFalse(lock.hasWaiters(c));
785                 lock.unlock();
786             }});
787 
788         await(pleaseSignal);
789         lock.lock();
790         assertHasWaiters(lock, c, t);
791         assertTrue(lock.hasWaiters(c));
792         c.signal();
793         assertHasNoWaiters(lock, c);
794         assertFalse(lock.hasWaiters(c));
795         lock.unlock();
796         awaitTermination(t);
797         assertHasNoWaiters(lock, c);
798     }
799 
800     /**
801      * getWaitQueueLength returns number of waiting threads
802      */
testGetWaitQueueLength()803     public void testGetWaitQueueLength()      { testGetWaitQueueLength(false); }
testGetWaitQueueLength_fair()804     public void testGetWaitQueueLength_fair() { testGetWaitQueueLength(true); }
testGetWaitQueueLength(boolean fair)805     public void testGetWaitQueueLength(boolean fair) {
806         final PublicReentrantLock lock = new PublicReentrantLock(fair);
807         final Condition c = lock.newCondition();
808         final CountDownLatch locked1 = new CountDownLatch(1);
809         final CountDownLatch locked2 = new CountDownLatch(1);
810         Thread t1 = new Thread(new CheckedRunnable() {
811             public void realRun() throws InterruptedException {
812                 lock.lock();
813                 assertFalse(lock.hasWaiters(c));
814                 assertEquals(0, lock.getWaitQueueLength(c));
815                 locked1.countDown();
816                 c.await();
817                 lock.unlock();
818             }});
819 
820         Thread t2 = new Thread(new CheckedRunnable() {
821             public void realRun() throws InterruptedException {
822                 lock.lock();
823                 assertTrue(lock.hasWaiters(c));
824                 assertEquals(1, lock.getWaitQueueLength(c));
825                 locked2.countDown();
826                 c.await();
827                 lock.unlock();
828             }});
829 
830         lock.lock();
831         assertEquals(0, lock.getWaitQueueLength(c));
832         lock.unlock();
833 
834         t1.start();
835         await(locked1);
836 
837         lock.lock();
838         assertHasWaiters(lock, c, t1);
839         assertEquals(1, lock.getWaitQueueLength(c));
840         lock.unlock();
841 
842         t2.start();
843         await(locked2);
844 
845         lock.lock();
846         assertHasWaiters(lock, c, t1, t2);
847         assertEquals(2, lock.getWaitQueueLength(c));
848         c.signalAll();
849         assertHasNoWaiters(lock, c);
850         lock.unlock();
851 
852         awaitTermination(t1);
853         awaitTermination(t2);
854 
855         assertHasNoWaiters(lock, c);
856     }
857 
858     /**
859      * getWaitingThreads returns only and all waiting threads
860      */
testGetWaitingThreads()861     public void testGetWaitingThreads()      { testGetWaitingThreads(false); }
testGetWaitingThreads_fair()862     public void testGetWaitingThreads_fair() { testGetWaitingThreads(true); }
testGetWaitingThreads(boolean fair)863     public void testGetWaitingThreads(boolean fair) {
864         final PublicReentrantLock lock = new PublicReentrantLock(fair);
865         final Condition c = lock.newCondition();
866         final CountDownLatch locked1 = new CountDownLatch(1);
867         final CountDownLatch locked2 = new CountDownLatch(1);
868         Thread t1 = new Thread(new CheckedRunnable() {
869             public void realRun() throws InterruptedException {
870                 lock.lock();
871                 assertTrue(lock.getWaitingThreads(c).isEmpty());
872                 locked1.countDown();
873                 c.await();
874                 lock.unlock();
875             }});
876 
877         Thread t2 = new Thread(new CheckedRunnable() {
878             public void realRun() throws InterruptedException {
879                 lock.lock();
880                 assertFalse(lock.getWaitingThreads(c).isEmpty());
881                 locked2.countDown();
882                 c.await();
883                 lock.unlock();
884             }});
885 
886         lock.lock();
887         assertTrue(lock.getWaitingThreads(c).isEmpty());
888         lock.unlock();
889 
890         t1.start();
891         await(locked1);
892 
893         lock.lock();
894         assertHasWaiters(lock, c, t1);
895         assertTrue(lock.getWaitingThreads(c).contains(t1));
896         assertFalse(lock.getWaitingThreads(c).contains(t2));
897         assertEquals(1, lock.getWaitingThreads(c).size());
898         lock.unlock();
899 
900         t2.start();
901         await(locked2);
902 
903         lock.lock();
904         assertHasWaiters(lock, c, t1, t2);
905         assertTrue(lock.getWaitingThreads(c).contains(t1));
906         assertTrue(lock.getWaitingThreads(c).contains(t2));
907         assertEquals(2, lock.getWaitingThreads(c).size());
908         c.signalAll();
909         assertHasNoWaiters(lock, c);
910         lock.unlock();
911 
912         awaitTermination(t1);
913         awaitTermination(t2);
914 
915         assertHasNoWaiters(lock, c);
916     }
917 
918     /**
919      * awaitUninterruptibly is uninterruptible
920      */
testAwaitUninterruptibly()921     public void testAwaitUninterruptibly()      { testAwaitUninterruptibly(false); }
testAwaitUninterruptibly_fair()922     public void testAwaitUninterruptibly_fair() { testAwaitUninterruptibly(true); }
testAwaitUninterruptibly(boolean fair)923     public void testAwaitUninterruptibly(boolean fair) {
924         final ReentrantLock lock = new ReentrantLock(fair);
925         final Condition condition = lock.newCondition();
926         final CountDownLatch pleaseInterrupt = new CountDownLatch(2);
927 
928         Thread t1 = newStartedThread(new CheckedRunnable() {
929             public void realRun() {
930                 // Interrupt before awaitUninterruptibly
931                 lock.lock();
932                 pleaseInterrupt.countDown();
933                 Thread.currentThread().interrupt();
934                 condition.awaitUninterruptibly();
935                 assertTrue(Thread.interrupted());
936                 lock.unlock();
937             }});
938 
939         Thread t2 = newStartedThread(new CheckedRunnable() {
940             public void realRun() {
941                 // Interrupt during awaitUninterruptibly
942                 lock.lock();
943                 pleaseInterrupt.countDown();
944                 condition.awaitUninterruptibly();
945                 assertTrue(Thread.interrupted());
946                 lock.unlock();
947             }});
948 
949         await(pleaseInterrupt);
950         t2.interrupt();
951         lock.lock();
952         lock.unlock();
953         assertThreadBlocks(t1, Thread.State.WAITING);
954         assertThreadBlocks(t2, Thread.State.WAITING);
955 
956         lock.lock();
957         condition.signalAll();
958         lock.unlock();
959 
960         awaitTermination(t1);
961         awaitTermination(t2);
962     }
963 
964     /**
965      * await/awaitNanos/awaitUntil is interruptible
966      */
testInterruptible_await()967     public void testInterruptible_await()           { testInterruptible(false, AwaitMethod.await); }
testInterruptible_await_fair()968     public void testInterruptible_await_fair()      { testInterruptible(true,  AwaitMethod.await); }
testInterruptible_awaitTimed()969     public void testInterruptible_awaitTimed()      { testInterruptible(false, AwaitMethod.awaitTimed); }
testInterruptible_awaitTimed_fair()970     public void testInterruptible_awaitTimed_fair() { testInterruptible(true,  AwaitMethod.awaitTimed); }
testInterruptible_awaitNanos()971     public void testInterruptible_awaitNanos()      { testInterruptible(false, AwaitMethod.awaitNanos); }
testInterruptible_awaitNanos_fair()972     public void testInterruptible_awaitNanos_fair() { testInterruptible(true,  AwaitMethod.awaitNanos); }
testInterruptible_awaitUntil()973     public void testInterruptible_awaitUntil()      { testInterruptible(false, AwaitMethod.awaitUntil); }
testInterruptible_awaitUntil_fair()974     public void testInterruptible_awaitUntil_fair() { testInterruptible(true,  AwaitMethod.awaitUntil); }
testInterruptible(boolean fair, final AwaitMethod awaitMethod)975     public void testInterruptible(boolean fair, final AwaitMethod awaitMethod) {
976         final PublicReentrantLock lock =
977             new PublicReentrantLock(fair);
978         final Condition c = lock.newCondition();
979         final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
980         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
981             public void realRun() throws InterruptedException {
982                 lock.lock();
983                 assertLockedByMoi(lock);
984                 assertHasNoWaiters(lock, c);
985                 pleaseInterrupt.countDown();
986                 try {
987                     await(c, awaitMethod);
988                 } finally {
989                     assertLockedByMoi(lock);
990                     assertHasNoWaiters(lock, c);
991                     lock.unlock();
992                     assertFalse(Thread.interrupted());
993                 }
994             }});
995 
996         await(pleaseInterrupt);
997         assertHasWaiters(lock, c, t);
998         t.interrupt();
999         awaitTermination(t);
1000         assertNotLocked(lock);
1001     }
1002 
1003     /**
1004      * signalAll wakes up all threads
1005      */
testSignalAll_await()1006     public void testSignalAll_await()           { testSignalAll(false, AwaitMethod.await); }
testSignalAll_await_fair()1007     public void testSignalAll_await_fair()      { testSignalAll(true,  AwaitMethod.await); }
testSignalAll_awaitTimed()1008     public void testSignalAll_awaitTimed()      { testSignalAll(false, AwaitMethod.awaitTimed); }
testSignalAll_awaitTimed_fair()1009     public void testSignalAll_awaitTimed_fair() { testSignalAll(true,  AwaitMethod.awaitTimed); }
testSignalAll_awaitNanos()1010     public void testSignalAll_awaitNanos()      { testSignalAll(false, AwaitMethod.awaitNanos); }
testSignalAll_awaitNanos_fair()1011     public void testSignalAll_awaitNanos_fair() { testSignalAll(true,  AwaitMethod.awaitNanos); }
testSignalAll_awaitUntil()1012     public void testSignalAll_awaitUntil()      { testSignalAll(false, AwaitMethod.awaitUntil); }
testSignalAll_awaitUntil_fair()1013     public void testSignalAll_awaitUntil_fair() { testSignalAll(true,  AwaitMethod.awaitUntil); }
testSignalAll(boolean fair, final AwaitMethod awaitMethod)1014     public void testSignalAll(boolean fair, final AwaitMethod awaitMethod) {
1015         final PublicReentrantLock lock = new PublicReentrantLock(fair);
1016         final Condition c = lock.newCondition();
1017         final CountDownLatch pleaseSignal = new CountDownLatch(2);
1018         class Awaiter extends CheckedRunnable {
1019             public void realRun() throws InterruptedException {
1020                 lock.lock();
1021                 pleaseSignal.countDown();
1022                 await(c, awaitMethod);
1023                 lock.unlock();
1024             }
1025         }
1026 
1027         Thread t1 = newStartedThread(new Awaiter());
1028         Thread t2 = newStartedThread(new Awaiter());
1029 
1030         await(pleaseSignal);
1031         lock.lock();
1032         assertHasWaiters(lock, c, t1, t2);
1033         c.signalAll();
1034         assertHasNoWaiters(lock, c);
1035         lock.unlock();
1036         awaitTermination(t1);
1037         awaitTermination(t2);
1038     }
1039 
1040     /**
1041      * signal wakes up waiting threads in FIFO order
1042      */
testSignalWakesFifo()1043     public void testSignalWakesFifo()      { testSignalWakesFifo(false); }
testSignalWakesFifo_fair()1044     public void testSignalWakesFifo_fair() { testSignalWakesFifo(true); }
testSignalWakesFifo(boolean fair)1045     public void testSignalWakesFifo(boolean fair) {
1046         final PublicReentrantLock lock =
1047             new PublicReentrantLock(fair);
1048         final Condition c = lock.newCondition();
1049         final CountDownLatch locked1 = new CountDownLatch(1);
1050         final CountDownLatch locked2 = new CountDownLatch(1);
1051         Thread t1 = newStartedThread(new CheckedRunnable() {
1052             public void realRun() throws InterruptedException {
1053                 lock.lock();
1054                 locked1.countDown();
1055                 c.await();
1056                 lock.unlock();
1057             }});
1058 
1059         await(locked1);
1060 
1061         Thread t2 = newStartedThread(new CheckedRunnable() {
1062             public void realRun() throws InterruptedException {
1063                 lock.lock();
1064                 locked2.countDown();
1065                 c.await();
1066                 lock.unlock();
1067             }});
1068 
1069         await(locked2);
1070 
1071         lock.lock();
1072         assertHasWaiters(lock, c, t1, t2);
1073         assertFalse(lock.hasQueuedThreads());
1074         c.signal();
1075         assertHasWaiters(lock, c, t2);
1076         assertTrue(lock.hasQueuedThread(t1));
1077         assertFalse(lock.hasQueuedThread(t2));
1078         c.signal();
1079         assertHasNoWaiters(lock, c);
1080         assertTrue(lock.hasQueuedThread(t1));
1081         assertTrue(lock.hasQueuedThread(t2));
1082         lock.unlock();
1083         awaitTermination(t1);
1084         awaitTermination(t2);
1085     }
1086 
1087     /**
1088      * await after multiple reentrant locking preserves lock count
1089      */
testAwaitLockCount()1090     public void testAwaitLockCount()      { testAwaitLockCount(false); }
testAwaitLockCount_fair()1091     public void testAwaitLockCount_fair() { testAwaitLockCount(true); }
testAwaitLockCount(boolean fair)1092     public void testAwaitLockCount(boolean fair) {
1093         final PublicReentrantLock lock = new PublicReentrantLock(fair);
1094         final Condition c = lock.newCondition();
1095         final CountDownLatch pleaseSignal = new CountDownLatch(2);
1096         Thread t1 = newStartedThread(new CheckedRunnable() {
1097             public void realRun() throws InterruptedException {
1098                 lock.lock();
1099                 assertLockedByMoi(lock);
1100                 assertEquals(1, lock.getHoldCount());
1101                 pleaseSignal.countDown();
1102                 c.await();
1103                 assertLockedByMoi(lock);
1104                 assertEquals(1, lock.getHoldCount());
1105                 lock.unlock();
1106             }});
1107 
1108         Thread t2 = newStartedThread(new CheckedRunnable() {
1109             public void realRun() throws InterruptedException {
1110                 lock.lock();
1111                 lock.lock();
1112                 assertLockedByMoi(lock);
1113                 assertEquals(2, lock.getHoldCount());
1114                 pleaseSignal.countDown();
1115                 c.await();
1116                 assertLockedByMoi(lock);
1117                 assertEquals(2, lock.getHoldCount());
1118                 lock.unlock();
1119                 lock.unlock();
1120             }});
1121 
1122         await(pleaseSignal);
1123         lock.lock();
1124         assertHasWaiters(lock, c, t1, t2);
1125         assertEquals(1, lock.getHoldCount());
1126         c.signalAll();
1127         assertHasNoWaiters(lock, c);
1128         lock.unlock();
1129         awaitTermination(t1);
1130         awaitTermination(t2);
1131     }
1132 
1133     /**
1134      * A serialized lock deserializes as unlocked
1135      */
testSerialization()1136     public void testSerialization()      { testSerialization(false); }
testSerialization_fair()1137     public void testSerialization_fair() { testSerialization(true); }
testSerialization(boolean fair)1138     public void testSerialization(boolean fair) {
1139         final ReentrantLock lock = new ReentrantLock(fair);
1140         lock.lock();
1141 
1142         ReentrantLock clone = serialClone(lock);
1143         assertEquals(lock.isFair(), clone.isFair());
1144         assertTrue(lock.isLocked());
1145         assertFalse(clone.isLocked());
1146         assertEquals(1, lock.getHoldCount());
1147         assertEquals(0, clone.getHoldCount());
1148         clone.lock();
1149         clone.lock();
1150         assertTrue(clone.isLocked());
1151         assertEquals(2, clone.getHoldCount());
1152         assertEquals(1, lock.getHoldCount());
1153         clone.unlock();
1154         clone.unlock();
1155         assertTrue(lock.isLocked());
1156         assertFalse(clone.isLocked());
1157     }
1158 
1159     /**
1160      * toString indicates current lock state
1161      */
testToString()1162     public void testToString()      { testToString(false); }
testToString_fair()1163     public void testToString_fair() { testToString(true); }
testToString(boolean fair)1164     public void testToString(boolean fair) {
1165         final ReentrantLock lock = new ReentrantLock(fair);
1166         assertTrue(lock.toString().contains("Unlocked"));
1167         lock.lock();
1168         assertTrue(lock.toString().contains("Locked by"));
1169         lock.unlock();
1170         assertTrue(lock.toString().contains("Unlocked"));
1171     }
1172 
1173     /**
1174      * Tests scenario for JDK-8187408
1175      * AbstractQueuedSynchronizer wait queue corrupted when thread awaits without holding the lock
1176      */
testBug8187408()1177     public void testBug8187408() throws InterruptedException {
1178         final ThreadLocalRandom rnd = ThreadLocalRandom.current();
1179         final AwaitMethod awaitMethod = randomAwaitMethod();
1180         final int nThreads = rnd.nextInt(2, 10);
1181         final ReentrantLock lock = new ReentrantLock();
1182         final Condition cond = lock.newCondition();
1183         final CountDownLatch done = new CountDownLatch(nThreads);
1184         final ArrayList<Thread> threads = new ArrayList<>();
1185 
1186         Runnable rogue = () -> {
1187             while (done.getCount() > 0) {
1188                 try {
1189                     // call await without holding lock?!
1190                     await(cond, awaitMethod);
1191                     throw new AssertionError("should throw");
1192                 }
1193                 catch (IllegalMonitorStateException success) {}
1194                 catch (Throwable fail) { threadUnexpectedException(fail); }}};
1195         Thread rogueThread = new Thread(rogue, "rogue");
1196         threads.add(rogueThread);
1197         rogueThread.start();
1198 
1199         Runnable waiter = () -> {
1200             lock.lock();
1201             try {
1202                 done.countDown();
1203                 cond.await();
1204             } catch (Throwable fail) {
1205                 threadUnexpectedException(fail);
1206             } finally {
1207                 lock.unlock();
1208             }};
1209         for (int i = 0; i < nThreads; i++) {
1210             Thread thread = new Thread(waiter, "waiter");
1211             threads.add(thread);
1212             thread.start();
1213         }
1214 
1215         assertTrue(done.await(LONG_DELAY_MS, MILLISECONDS));
1216         lock.lock();
1217         try {
1218             assertEquals(nThreads, lock.getWaitQueueLength(cond));
1219         } finally {
1220             cond.signalAll();
1221             lock.unlock();
1222         }
1223         for (Thread thread : threads) {
1224             thread.join(LONG_DELAY_MS);
1225             assertFalse(thread.isAlive());
1226         }
1227     }
1228 
1229     /**
1230      * ThreadMXBean reports the blockers that we expect.
1231      */
testBlockers()1232     public void testBlockers() {
1233         if (!testImplementationDetails) return;
1234         final boolean fair = randomBoolean();
1235         final boolean timedAcquire = randomBoolean();
1236         final boolean timedAwait = randomBoolean();
1237         final String syncClassName = fair
1238             ? "ReentrantLock$FairSync"
1239             : "ReentrantLock$NonfairSync";
1240         final String conditionClassName
1241             = "AbstractQueuedSynchronizer$ConditionObject";
1242         final Thread.State expectedAcquireState = timedAcquire
1243             ? Thread.State.TIMED_WAITING
1244             : Thread.State.WAITING;
1245         final Thread.State expectedAwaitState = timedAwait
1246             ? Thread.State.TIMED_WAITING
1247             : Thread.State.WAITING;
1248         final Lock lock = new ReentrantLock(fair);
1249         final Condition condition = lock.newCondition();
1250         final AtomicBoolean conditionSatisfied = new AtomicBoolean(false);
1251         lock.lock();
1252         final Thread thread = newStartedThread((Action) () -> {
1253             if (timedAcquire)
1254                 lock.tryLock(LONGER_DELAY_MS, MILLISECONDS);
1255             else
1256                 lock.lock();
1257             while (!conditionSatisfied.get())
1258                 if (timedAwait)
1259                     condition.await(LONGER_DELAY_MS, MILLISECONDS);
1260                 else
1261                     condition.await();
1262         });
1263         Callable<Boolean> waitingForLock = () -> {
1264             String className;
1265             return thread.getState() == expectedAcquireState
1266             && (className = blockerClassName(thread)) != null
1267             && className.endsWith(syncClassName);
1268         };
1269         waitForThreadToEnterWaitState(thread, waitingForLock);
1270 
1271         lock.unlock();
1272         Callable<Boolean> waitingForCondition = () -> {
1273             String className;
1274             return thread.getState() == expectedAwaitState
1275             && (className = blockerClassName(thread)) != null
1276             && className.endsWith(conditionClassName);
1277         };
1278         waitForThreadToEnterWaitState(thread, waitingForCondition);
1279 
1280         // politely release the waiter
1281         conditionSatisfied.set(true);
1282         lock.lock();
1283         try {
1284             condition.signal();
1285         } finally { lock.unlock(); }
1286 
1287         awaitTermination(thread);
1288     }
1289 }
1290