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