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.Arrays;
39 import java.util.Collection;
40 import java.util.HashSet;
41 import java.util.concurrent.CountDownLatch;
42 import java.util.concurrent.atomic.AtomicBoolean;
43 import java.util.concurrent.locks.Condition;
44 import java.util.concurrent.locks.Lock;
45 import java.util.concurrent.locks.ReentrantReadWriteLock;
46 
47 import junit.framework.Test;
48 import junit.framework.TestSuite;
49 
50 @SuppressWarnings("WaitNotInLoop") // we implement spurious-wakeup freedom
51 public class ReentrantReadWriteLockTest extends JSR166TestCase {
main(String[] args)52     public static void main(String[] args) {
53         main(suite(), args);
54     }
suite()55     public static Test suite() {
56         return new TestSuite(ReentrantReadWriteLockTest.class);
57     }
58 
59     /**
60      * A runnable calling lockInterruptibly
61      */
62     class InterruptibleLockRunnable extends CheckedRunnable {
63         final ReentrantReadWriteLock lock;
InterruptibleLockRunnable(ReentrantReadWriteLock l)64         InterruptibleLockRunnable(ReentrantReadWriteLock l) { lock = l; }
realRun()65         public void realRun() throws InterruptedException {
66             lock.writeLock().lockInterruptibly();
67         }
68     }
69 
70     /**
71      * A runnable calling lockInterruptibly that expects to be
72      * interrupted
73      */
74     class InterruptedLockRunnable extends CheckedInterruptedRunnable {
75         final ReentrantReadWriteLock lock;
InterruptedLockRunnable(ReentrantReadWriteLock l)76         InterruptedLockRunnable(ReentrantReadWriteLock l) { lock = l; }
realRun()77         public void realRun() throws InterruptedException {
78             lock.writeLock().lockInterruptibly();
79         }
80     }
81 
82     /**
83      * Subclass to expose protected methods
84      */
85     static class PublicReentrantReadWriteLock extends ReentrantReadWriteLock {
PublicReentrantReadWriteLock()86         PublicReentrantReadWriteLock() { super(); }
PublicReentrantReadWriteLock(boolean fair)87         PublicReentrantReadWriteLock(boolean fair) { super(fair); }
getOwner()88         public Thread getOwner() {
89             return super.getOwner();
90         }
getQueuedThreads()91         public Collection<Thread> getQueuedThreads() {
92             return super.getQueuedThreads();
93         }
getWaitingThreads(Condition c)94         public Collection<Thread> getWaitingThreads(Condition c) {
95             return super.getWaitingThreads(c);
96         }
97     }
98 
99     /**
100      * Releases write lock, checking that it had a hold count of 1.
101      */
releaseWriteLock(PublicReentrantReadWriteLock lock)102     void releaseWriteLock(PublicReentrantReadWriteLock lock) {
103         ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
104         assertWriteLockedByMoi(lock);
105         assertEquals(1, lock.getWriteHoldCount());
106         writeLock.unlock();
107         assertNotWriteLocked(lock);
108     }
109 
110     /**
111      * Spin-waits until lock.hasQueuedThread(t) becomes true.
112      */
waitForQueuedThread(PublicReentrantReadWriteLock lock, Thread t)113     void waitForQueuedThread(PublicReentrantReadWriteLock lock, Thread t) {
114         long startTime = System.nanoTime();
115         while (!lock.hasQueuedThread(t)) {
116             if (millisElapsedSince(startTime) > LONG_DELAY_MS)
117                 throw new AssertionError("timed out");
118             Thread.yield();
119         }
120         assertTrue(t.isAlive());
121         assertNotSame(t, lock.getOwner());
122     }
123 
124     /**
125      * Checks that lock is not write-locked.
126      */
assertNotWriteLocked(PublicReentrantReadWriteLock lock)127     void assertNotWriteLocked(PublicReentrantReadWriteLock lock) {
128         assertFalse(lock.isWriteLocked());
129         assertFalse(lock.isWriteLockedByCurrentThread());
130         assertFalse(lock.writeLock().isHeldByCurrentThread());
131         assertEquals(0, lock.getWriteHoldCount());
132         assertEquals(0, lock.writeLock().getHoldCount());
133         assertNull(lock.getOwner());
134     }
135 
136     /**
137      * Checks that lock is write-locked by the given thread.
138      */
assertWriteLockedBy(PublicReentrantReadWriteLock lock, Thread t)139     void assertWriteLockedBy(PublicReentrantReadWriteLock lock, Thread t) {
140         assertTrue(lock.isWriteLocked());
141         assertSame(t, lock.getOwner());
142         assertEquals(t == Thread.currentThread(),
143                      lock.isWriteLockedByCurrentThread());
144         assertEquals(t == Thread.currentThread(),
145                      lock.writeLock().isHeldByCurrentThread());
146         assertEquals(t == Thread.currentThread(),
147                      lock.getWriteHoldCount() > 0);
148         assertEquals(t == Thread.currentThread(),
149                      lock.writeLock().getHoldCount() > 0);
150         assertEquals(0, lock.getReadLockCount());
151     }
152 
153     /**
154      * Checks that lock is write-locked by the current thread.
155      */
assertWriteLockedByMoi(PublicReentrantReadWriteLock lock)156     void assertWriteLockedByMoi(PublicReentrantReadWriteLock lock) {
157         assertWriteLockedBy(lock, Thread.currentThread());
158     }
159 
160     /**
161      * Checks that condition c has no waiters.
162      */
assertHasNoWaiters(PublicReentrantReadWriteLock lock, Condition c)163     void assertHasNoWaiters(PublicReentrantReadWriteLock lock, Condition c) {
164         assertHasWaiters(lock, c, new Thread[] {});
165     }
166 
167     /**
168      * Checks that condition c has exactly the given waiter threads.
169      */
assertHasWaiters(PublicReentrantReadWriteLock lock, Condition c, Thread... threads)170     void assertHasWaiters(PublicReentrantReadWriteLock lock, Condition c,
171                           Thread... threads) {
172         lock.writeLock().lock();
173         assertEquals(threads.length > 0, lock.hasWaiters(c));
174         assertEquals(threads.length, lock.getWaitQueueLength(c));
175         assertEquals(threads.length == 0, lock.getWaitingThreads(c).isEmpty());
176         assertEquals(threads.length, lock.getWaitingThreads(c).size());
177         assertEquals(new HashSet<Thread>(lock.getWaitingThreads(c)),
178                      new HashSet<Thread>(Arrays.asList(threads)));
179         lock.writeLock().unlock();
180     }
181 
182     enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil }
183 
184     /**
185      * Awaits condition "indefinitely" using the specified AwaitMethod.
186      */
await(Condition c, AwaitMethod awaitMethod)187     void await(Condition c, AwaitMethod awaitMethod)
188             throws InterruptedException {
189         long timeoutMillis = 2 * LONG_DELAY_MS;
190         switch (awaitMethod) {
191         case await:
192             c.await();
193             break;
194         case awaitTimed:
195             assertTrue(c.await(timeoutMillis, MILLISECONDS));
196             break;
197         case awaitNanos:
198             long timeoutNanos = MILLISECONDS.toNanos(timeoutMillis);
199             long nanosRemaining = c.awaitNanos(timeoutNanos);
200             assertTrue(nanosRemaining > timeoutNanos / 2);
201             assertTrue(nanosRemaining <= timeoutNanos);
202             break;
203         case awaitUntil:
204             assertTrue(c.awaitUntil(delayedDate(timeoutMillis)));
205             break;
206         default:
207             throw new AssertionError();
208         }
209     }
210 
211     /**
212      * Constructor sets given fairness, and is in unlocked state
213      */
testConstructor()214     public void testConstructor() {
215         PublicReentrantReadWriteLock lock;
216 
217         lock = new PublicReentrantReadWriteLock();
218         assertFalse(lock.isFair());
219         assertNotWriteLocked(lock);
220         assertEquals(0, lock.getReadLockCount());
221 
222         lock = new PublicReentrantReadWriteLock(true);
223         assertTrue(lock.isFair());
224         assertNotWriteLocked(lock);
225         assertEquals(0, lock.getReadLockCount());
226 
227         lock = new PublicReentrantReadWriteLock(false);
228         assertFalse(lock.isFair());
229         assertNotWriteLocked(lock);
230         assertEquals(0, lock.getReadLockCount());
231     }
232 
233     /**
234      * write-locking and read-locking an unlocked lock succeed
235      */
testLock()236     public void testLock()      { testLock(false); }
testLock_fair()237     public void testLock_fair() { testLock(true); }
testLock(boolean fair)238     public void testLock(boolean fair) {
239         PublicReentrantReadWriteLock lock =
240             new PublicReentrantReadWriteLock(fair);
241         assertNotWriteLocked(lock);
242         lock.writeLock().lock();
243         assertWriteLockedByMoi(lock);
244         lock.writeLock().unlock();
245         assertNotWriteLocked(lock);
246         assertEquals(0, lock.getReadLockCount());
247         lock.readLock().lock();
248         assertNotWriteLocked(lock);
249         assertEquals(1, lock.getReadLockCount());
250         lock.readLock().unlock();
251         assertNotWriteLocked(lock);
252         assertEquals(0, lock.getReadLockCount());
253     }
254 
255     /**
256      * getWriteHoldCount returns number of recursive holds
257      */
testGetWriteHoldCount()258     public void testGetWriteHoldCount()      { testGetWriteHoldCount(false); }
testGetWriteHoldCount_fair()259     public void testGetWriteHoldCount_fair() { testGetWriteHoldCount(true); }
testGetWriteHoldCount(boolean fair)260     public void testGetWriteHoldCount(boolean fair) {
261         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
262         for (int i = 1; i <= SIZE; i++) {
263             lock.writeLock().lock();
264             assertEquals(i,lock.getWriteHoldCount());
265         }
266         for (int i = SIZE; i > 0; i--) {
267             lock.writeLock().unlock();
268             assertEquals(i - 1,lock.getWriteHoldCount());
269         }
270     }
271 
272     /**
273      * writelock.getHoldCount returns number of recursive holds
274      */
testGetHoldCount()275     public void testGetHoldCount()      { testGetHoldCount(false); }
testGetHoldCount_fair()276     public void testGetHoldCount_fair() { testGetHoldCount(true); }
testGetHoldCount(boolean fair)277     public void testGetHoldCount(boolean fair) {
278         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
279         for (int i = 1; i <= SIZE; i++) {
280             lock.writeLock().lock();
281             assertEquals(i,lock.writeLock().getHoldCount());
282         }
283         for (int i = SIZE; i > 0; i--) {
284             lock.writeLock().unlock();
285             assertEquals(i - 1,lock.writeLock().getHoldCount());
286         }
287     }
288 
289     /**
290      * getReadHoldCount returns number of recursive holds
291      */
testGetReadHoldCount()292     public void testGetReadHoldCount()      { testGetReadHoldCount(false); }
testGetReadHoldCount_fair()293     public void testGetReadHoldCount_fair() { testGetReadHoldCount(true); }
testGetReadHoldCount(boolean fair)294     public void testGetReadHoldCount(boolean fair) {
295         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
296         for (int i = 1; i <= SIZE; i++) {
297             lock.readLock().lock();
298             assertEquals(i,lock.getReadHoldCount());
299         }
300         for (int i = SIZE; i > 0; i--) {
301             lock.readLock().unlock();
302             assertEquals(i - 1,lock.getReadHoldCount());
303         }
304     }
305 
306     /**
307      * write-unlocking an unlocked lock throws IllegalMonitorStateException
308      */
testWriteUnlock_IMSE()309     public void testWriteUnlock_IMSE()      { testWriteUnlock_IMSE(false); }
testWriteUnlock_IMSE_fair()310     public void testWriteUnlock_IMSE_fair() { testWriteUnlock_IMSE(true); }
testWriteUnlock_IMSE(boolean fair)311     public void testWriteUnlock_IMSE(boolean fair) {
312         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
313         try {
314             lock.writeLock().unlock();
315             shouldThrow();
316         } catch (IllegalMonitorStateException success) {}
317     }
318 
319     /**
320      * read-unlocking an unlocked lock throws IllegalMonitorStateException
321      */
testReadUnlock_IMSE()322     public void testReadUnlock_IMSE()      { testReadUnlock_IMSE(false); }
testReadUnlock_IMSE_fair()323     public void testReadUnlock_IMSE_fair() { testReadUnlock_IMSE(true); }
testReadUnlock_IMSE(boolean fair)324     public void testReadUnlock_IMSE(boolean fair) {
325         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
326         try {
327             lock.readLock().unlock();
328             shouldThrow();
329         } catch (IllegalMonitorStateException success) {}
330     }
331 
332     /**
333      * write-lockInterruptibly is interruptible
334      */
testWriteLockInterruptibly_Interruptible()335     public void testWriteLockInterruptibly_Interruptible()      { testWriteLockInterruptibly_Interruptible(false); }
testWriteLockInterruptibly_Interruptible_fair()336     public void testWriteLockInterruptibly_Interruptible_fair() { testWriteLockInterruptibly_Interruptible(true); }
testWriteLockInterruptibly_Interruptible(boolean fair)337     public void testWriteLockInterruptibly_Interruptible(boolean fair) {
338         final PublicReentrantReadWriteLock lock =
339             new PublicReentrantReadWriteLock(fair);
340         lock.writeLock().lock();
341         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
342             public void realRun() throws InterruptedException {
343                 lock.writeLock().lockInterruptibly();
344             }});
345 
346         waitForQueuedThread(lock, t);
347         t.interrupt();
348         awaitTermination(t);
349         releaseWriteLock(lock);
350     }
351 
352     /**
353      * timed write-tryLock is interruptible
354      */
testWriteTryLock_Interruptible()355     public void testWriteTryLock_Interruptible()      { testWriteTryLock_Interruptible(false); }
testWriteTryLock_Interruptible_fair()356     public void testWriteTryLock_Interruptible_fair() { testWriteTryLock_Interruptible(true); }
testWriteTryLock_Interruptible(boolean fair)357     public void testWriteTryLock_Interruptible(boolean fair) {
358         final PublicReentrantReadWriteLock lock =
359             new PublicReentrantReadWriteLock(fair);
360         lock.writeLock().lock();
361         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
362             public void realRun() throws InterruptedException {
363                 lock.writeLock().tryLock(2 * LONG_DELAY_MS, MILLISECONDS);
364             }});
365 
366         waitForQueuedThread(lock, t);
367         t.interrupt();
368         awaitTermination(t);
369         releaseWriteLock(lock);
370     }
371 
372     /**
373      * read-lockInterruptibly is interruptible
374      */
testReadLockInterruptibly_Interruptible()375     public void testReadLockInterruptibly_Interruptible()      { testReadLockInterruptibly_Interruptible(false); }
testReadLockInterruptibly_Interruptible_fair()376     public void testReadLockInterruptibly_Interruptible_fair() { testReadLockInterruptibly_Interruptible(true); }
testReadLockInterruptibly_Interruptible(boolean fair)377     public void testReadLockInterruptibly_Interruptible(boolean fair) {
378         final PublicReentrantReadWriteLock lock =
379             new PublicReentrantReadWriteLock(fair);
380         lock.writeLock().lock();
381         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
382             public void realRun() throws InterruptedException {
383                 lock.readLock().lockInterruptibly();
384             }});
385 
386         waitForQueuedThread(lock, t);
387         t.interrupt();
388         awaitTermination(t);
389         releaseWriteLock(lock);
390     }
391 
392     /**
393      * timed read-tryLock is interruptible
394      */
testReadTryLock_Interruptible()395     public void testReadTryLock_Interruptible()      { testReadTryLock_Interruptible(false); }
testReadTryLock_Interruptible_fair()396     public void testReadTryLock_Interruptible_fair() { testReadTryLock_Interruptible(true); }
testReadTryLock_Interruptible(boolean fair)397     public void testReadTryLock_Interruptible(boolean fair) {
398         final PublicReentrantReadWriteLock lock =
399             new PublicReentrantReadWriteLock(fair);
400         lock.writeLock().lock();
401         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
402             public void realRun() throws InterruptedException {
403                 lock.readLock().tryLock(2 * LONG_DELAY_MS, MILLISECONDS);
404             }});
405 
406         waitForQueuedThread(lock, t);
407         t.interrupt();
408         awaitTermination(t);
409         releaseWriteLock(lock);
410     }
411 
412     /**
413      * write-tryLock on an unlocked lock succeeds
414      */
testWriteTryLock()415     public void testWriteTryLock()      { testWriteTryLock(false); }
testWriteTryLock_fair()416     public void testWriteTryLock_fair() { testWriteTryLock(true); }
testWriteTryLock(boolean fair)417     public void testWriteTryLock(boolean fair) {
418         final PublicReentrantReadWriteLock lock =
419             new PublicReentrantReadWriteLock(fair);
420         assertTrue(lock.writeLock().tryLock());
421         assertWriteLockedByMoi(lock);
422         assertTrue(lock.writeLock().tryLock());
423         assertWriteLockedByMoi(lock);
424         lock.writeLock().unlock();
425         releaseWriteLock(lock);
426     }
427 
428     /**
429      * write-tryLock fails if locked
430      */
testWriteTryLockWhenLocked()431     public void testWriteTryLockWhenLocked()      { testWriteTryLockWhenLocked(false); }
testWriteTryLockWhenLocked_fair()432     public void testWriteTryLockWhenLocked_fair() { testWriteTryLockWhenLocked(true); }
testWriteTryLockWhenLocked(boolean fair)433     public void testWriteTryLockWhenLocked(boolean fair) {
434         final PublicReentrantReadWriteLock lock =
435             new PublicReentrantReadWriteLock(fair);
436         lock.writeLock().lock();
437         Thread t = newStartedThread(new CheckedRunnable() {
438             public void realRun() {
439                 assertFalse(lock.writeLock().tryLock());
440             }});
441 
442         awaitTermination(t);
443         releaseWriteLock(lock);
444     }
445 
446     /**
447      * read-tryLock fails if locked
448      */
testReadTryLockWhenLocked()449     public void testReadTryLockWhenLocked()      { testReadTryLockWhenLocked(false); }
testReadTryLockWhenLocked_fair()450     public void testReadTryLockWhenLocked_fair() { testReadTryLockWhenLocked(true); }
testReadTryLockWhenLocked(boolean fair)451     public void testReadTryLockWhenLocked(boolean fair) {
452         final PublicReentrantReadWriteLock lock =
453             new PublicReentrantReadWriteLock(fair);
454         lock.writeLock().lock();
455         Thread t = newStartedThread(new CheckedRunnable() {
456             public void realRun() {
457                 assertFalse(lock.readLock().tryLock());
458             }});
459 
460         awaitTermination(t);
461         releaseWriteLock(lock);
462     }
463 
464     /**
465      * Multiple threads can hold a read lock when not write-locked
466      */
testMultipleReadLocks()467     public void testMultipleReadLocks()      { testMultipleReadLocks(false); }
testMultipleReadLocks_fair()468     public void testMultipleReadLocks_fair() { testMultipleReadLocks(true); }
testMultipleReadLocks(boolean fair)469     public void testMultipleReadLocks(boolean fair) {
470         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
471         lock.readLock().lock();
472         Thread t = newStartedThread(new CheckedRunnable() {
473             public void realRun() throws InterruptedException {
474                 assertTrue(lock.readLock().tryLock());
475                 lock.readLock().unlock();
476                 assertTrue(lock.readLock().tryLock(LONG_DELAY_MS, MILLISECONDS));
477                 lock.readLock().unlock();
478                 lock.readLock().lock();
479                 lock.readLock().unlock();
480             }});
481 
482         awaitTermination(t);
483         lock.readLock().unlock();
484     }
485 
486     /**
487      * A writelock succeeds only after a reading thread unlocks
488      */
testWriteAfterReadLock()489     public void testWriteAfterReadLock()      { testWriteAfterReadLock(false); }
testWriteAfterReadLock_fair()490     public void testWriteAfterReadLock_fair() { testWriteAfterReadLock(true); }
testWriteAfterReadLock(boolean fair)491     public void testWriteAfterReadLock(boolean fair) {
492         final PublicReentrantReadWriteLock lock =
493             new PublicReentrantReadWriteLock(fair);
494         lock.readLock().lock();
495         Thread t = newStartedThread(new CheckedRunnable() {
496             public void realRun() {
497                 assertEquals(1, lock.getReadLockCount());
498                 lock.writeLock().lock();
499                 assertEquals(0, lock.getReadLockCount());
500                 lock.writeLock().unlock();
501             }});
502         waitForQueuedThread(lock, t);
503         assertNotWriteLocked(lock);
504         assertEquals(1, lock.getReadLockCount());
505         lock.readLock().unlock();
506         assertEquals(0, lock.getReadLockCount());
507         awaitTermination(t);
508         assertNotWriteLocked(lock);
509     }
510 
511     /**
512      * A writelock succeeds only after reading threads unlock
513      */
testWriteAfterMultipleReadLocks()514     public void testWriteAfterMultipleReadLocks()      { testWriteAfterMultipleReadLocks(false); }
testWriteAfterMultipleReadLocks_fair()515     public void testWriteAfterMultipleReadLocks_fair() { testWriteAfterMultipleReadLocks(true); }
testWriteAfterMultipleReadLocks(boolean fair)516     public void testWriteAfterMultipleReadLocks(boolean fair) {
517         final PublicReentrantReadWriteLock lock =
518             new PublicReentrantReadWriteLock(fair);
519         lock.readLock().lock();
520         lock.readLock().lock();
521         Thread t1 = newStartedThread(new CheckedRunnable() {
522             public void realRun() {
523                 lock.readLock().lock();
524                 assertEquals(3, lock.getReadLockCount());
525                 lock.readLock().unlock();
526             }});
527         awaitTermination(t1);
528 
529         Thread t2 = newStartedThread(new CheckedRunnable() {
530             public void realRun() {
531                 assertEquals(2, lock.getReadLockCount());
532                 lock.writeLock().lock();
533                 assertEquals(0, lock.getReadLockCount());
534                 lock.writeLock().unlock();
535             }});
536         waitForQueuedThread(lock, t2);
537         assertNotWriteLocked(lock);
538         assertEquals(2, lock.getReadLockCount());
539         lock.readLock().unlock();
540         lock.readLock().unlock();
541         assertEquals(0, lock.getReadLockCount());
542         awaitTermination(t2);
543         assertNotWriteLocked(lock);
544     }
545 
546     /**
547      * A thread that tries to acquire a fair read lock (non-reentrantly)
548      * will block if there is a waiting writer thread
549      */
testReaderWriterReaderFairFifo()550     public void testReaderWriterReaderFairFifo() {
551         final PublicReentrantReadWriteLock lock =
552             new PublicReentrantReadWriteLock(true);
553         final AtomicBoolean t1GotLock = new AtomicBoolean(false);
554 
555         lock.readLock().lock();
556         Thread t1 = newStartedThread(new CheckedRunnable() {
557             public void realRun() {
558                 assertEquals(1, lock.getReadLockCount());
559                 lock.writeLock().lock();
560                 assertEquals(0, lock.getReadLockCount());
561                 t1GotLock.set(true);
562                 lock.writeLock().unlock();
563             }});
564         waitForQueuedThread(lock, t1);
565 
566         Thread t2 = newStartedThread(new CheckedRunnable() {
567             public void realRun() {
568                 assertEquals(1, lock.getReadLockCount());
569                 lock.readLock().lock();
570                 assertEquals(1, lock.getReadLockCount());
571                 assertTrue(t1GotLock.get());
572                 lock.readLock().unlock();
573             }});
574         waitForQueuedThread(lock, t2);
575         assertTrue(t1.isAlive());
576         assertNotWriteLocked(lock);
577         assertEquals(1, lock.getReadLockCount());
578         lock.readLock().unlock();
579         awaitTermination(t1);
580         awaitTermination(t2);
581         assertNotWriteLocked(lock);
582     }
583 
584     /**
585      * Readlocks succeed only after a writing thread unlocks
586      */
testReadAfterWriteLock()587     public void testReadAfterWriteLock()      { testReadAfterWriteLock(false); }
testReadAfterWriteLock_fair()588     public void testReadAfterWriteLock_fair() { testReadAfterWriteLock(true); }
testReadAfterWriteLock(boolean fair)589     public void testReadAfterWriteLock(boolean fair) {
590         final PublicReentrantReadWriteLock lock =
591             new PublicReentrantReadWriteLock(fair);
592         lock.writeLock().lock();
593         Thread t1 = newStartedThread(new CheckedRunnable() {
594             public void realRun() {
595                 lock.readLock().lock();
596                 lock.readLock().unlock();
597             }});
598         Thread t2 = newStartedThread(new CheckedRunnable() {
599             public void realRun() {
600                 lock.readLock().lock();
601                 lock.readLock().unlock();
602             }});
603 
604         waitForQueuedThread(lock, t1);
605         waitForQueuedThread(lock, t2);
606         releaseWriteLock(lock);
607         awaitTermination(t1);
608         awaitTermination(t2);
609     }
610 
611     /**
612      * Read trylock succeeds if write locked by current thread
613      */
testReadHoldingWriteLock()614     public void testReadHoldingWriteLock()      { testReadHoldingWriteLock(false); }
testReadHoldingWriteLock_fair()615     public void testReadHoldingWriteLock_fair() { testReadHoldingWriteLock(true); }
testReadHoldingWriteLock(boolean fair)616     public void testReadHoldingWriteLock(boolean fair) {
617         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
618         lock.writeLock().lock();
619         assertTrue(lock.readLock().tryLock());
620         lock.readLock().unlock();
621         lock.writeLock().unlock();
622     }
623 
624     /**
625      * Read trylock succeeds (barging) even in the presence of waiting
626      * readers and/or writers
627      */
testReadTryLockBarging()628     public void testReadTryLockBarging()      { testReadTryLockBarging(false); }
testReadTryLockBarging_fair()629     public void testReadTryLockBarging_fair() { testReadTryLockBarging(true); }
testReadTryLockBarging(boolean fair)630     public void testReadTryLockBarging(boolean fair) {
631         final PublicReentrantReadWriteLock lock =
632             new PublicReentrantReadWriteLock(fair);
633         lock.readLock().lock();
634 
635         Thread t1 = newStartedThread(new CheckedRunnable() {
636             public void realRun() {
637                 lock.writeLock().lock();
638                 lock.writeLock().unlock();
639             }});
640 
641         waitForQueuedThread(lock, t1);
642 
643         Thread t2 = newStartedThread(new CheckedRunnable() {
644             public void realRun() {
645                 lock.readLock().lock();
646                 lock.readLock().unlock();
647             }});
648 
649         if (fair)
650             waitForQueuedThread(lock, t2);
651 
652         Thread t3 = newStartedThread(new CheckedRunnable() {
653             public void realRun() {
654                 lock.readLock().tryLock();
655                 lock.readLock().unlock();
656             }});
657 
658         assertTrue(lock.getReadLockCount() > 0);
659         awaitTermination(t3);
660         assertTrue(t1.isAlive());
661         if (fair) assertTrue(t2.isAlive());
662         lock.readLock().unlock();
663         awaitTermination(t1);
664         awaitTermination(t2);
665     }
666 
667     /**
668      * Read lock succeeds if write locked by current thread even if
669      * other threads are waiting for readlock
670      */
testReadHoldingWriteLock2()671     public void testReadHoldingWriteLock2()      { testReadHoldingWriteLock2(false); }
testReadHoldingWriteLock2_fair()672     public void testReadHoldingWriteLock2_fair() { testReadHoldingWriteLock2(true); }
testReadHoldingWriteLock2(boolean fair)673     public void testReadHoldingWriteLock2(boolean fair) {
674         final PublicReentrantReadWriteLock lock =
675             new PublicReentrantReadWriteLock(fair);
676         lock.writeLock().lock();
677         lock.readLock().lock();
678         lock.readLock().unlock();
679 
680         Thread t1 = newStartedThread(new CheckedRunnable() {
681             public void realRun() {
682                 lock.readLock().lock();
683                 lock.readLock().unlock();
684             }});
685         Thread t2 = newStartedThread(new CheckedRunnable() {
686             public void realRun() {
687                 lock.readLock().lock();
688                 lock.readLock().unlock();
689             }});
690 
691         waitForQueuedThread(lock, t1);
692         waitForQueuedThread(lock, t2);
693         assertWriteLockedByMoi(lock);
694         lock.readLock().lock();
695         lock.readLock().unlock();
696         releaseWriteLock(lock);
697         awaitTermination(t1);
698         awaitTermination(t2);
699     }
700 
701     /**
702      * Read lock succeeds if write locked by current thread even if
703      * other threads are waiting for writelock
704      */
testReadHoldingWriteLock3()705     public void testReadHoldingWriteLock3()      { testReadHoldingWriteLock3(false); }
testReadHoldingWriteLock3_fair()706     public void testReadHoldingWriteLock3_fair() { testReadHoldingWriteLock3(true); }
testReadHoldingWriteLock3(boolean fair)707     public void testReadHoldingWriteLock3(boolean fair) {
708         final PublicReentrantReadWriteLock lock =
709             new PublicReentrantReadWriteLock(fair);
710         lock.writeLock().lock();
711         lock.readLock().lock();
712         lock.readLock().unlock();
713 
714         Thread t1 = newStartedThread(new CheckedRunnable() {
715             public void realRun() {
716                 lock.writeLock().lock();
717                 lock.writeLock().unlock();
718             }});
719         Thread t2 = newStartedThread(new CheckedRunnable() {
720             public void realRun() {
721                 lock.writeLock().lock();
722                 lock.writeLock().unlock();
723             }});
724 
725         waitForQueuedThread(lock, t1);
726         waitForQueuedThread(lock, t2);
727         assertWriteLockedByMoi(lock);
728         lock.readLock().lock();
729         lock.readLock().unlock();
730         assertWriteLockedByMoi(lock);
731         lock.writeLock().unlock();
732         awaitTermination(t1);
733         awaitTermination(t2);
734     }
735 
736     /**
737      * Write lock succeeds if write locked by current thread even if
738      * other threads are waiting for writelock
739      */
testWriteHoldingWriteLock4()740     public void testWriteHoldingWriteLock4()      { testWriteHoldingWriteLock4(false); }
testWriteHoldingWriteLock4_fair()741     public void testWriteHoldingWriteLock4_fair() { testWriteHoldingWriteLock4(true); }
testWriteHoldingWriteLock4(boolean fair)742     public void testWriteHoldingWriteLock4(boolean fair) {
743         final PublicReentrantReadWriteLock lock =
744             new PublicReentrantReadWriteLock(fair);
745         lock.writeLock().lock();
746         lock.writeLock().lock();
747         lock.writeLock().unlock();
748 
749         Thread t1 = newStartedThread(new CheckedRunnable() {
750             public void realRun() {
751                 lock.writeLock().lock();
752                 lock.writeLock().unlock();
753             }});
754         Thread t2 = newStartedThread(new CheckedRunnable() {
755             public void realRun() {
756                 lock.writeLock().lock();
757                 lock.writeLock().unlock();
758             }});
759 
760         waitForQueuedThread(lock, t1);
761         waitForQueuedThread(lock, t2);
762         assertWriteLockedByMoi(lock);
763         assertEquals(1, lock.getWriteHoldCount());
764         lock.writeLock().lock();
765         assertWriteLockedByMoi(lock);
766         assertEquals(2, lock.getWriteHoldCount());
767         lock.writeLock().unlock();
768         assertWriteLockedByMoi(lock);
769         assertEquals(1, lock.getWriteHoldCount());
770         lock.writeLock().unlock();
771         awaitTermination(t1);
772         awaitTermination(t2);
773     }
774 
775     /**
776      * Read tryLock succeeds if readlocked but not writelocked
777      */
testTryLockWhenReadLocked()778     public void testTryLockWhenReadLocked()      { testTryLockWhenReadLocked(false); }
testTryLockWhenReadLocked_fair()779     public void testTryLockWhenReadLocked_fair() { testTryLockWhenReadLocked(true); }
testTryLockWhenReadLocked(boolean fair)780     public void testTryLockWhenReadLocked(boolean fair) {
781         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
782         lock.readLock().lock();
783         Thread t = newStartedThread(new CheckedRunnable() {
784             public void realRun() {
785                 assertTrue(lock.readLock().tryLock());
786                 lock.readLock().unlock();
787             }});
788 
789         awaitTermination(t);
790         lock.readLock().unlock();
791     }
792 
793     /**
794      * write tryLock fails when readlocked
795      */
testWriteTryLockWhenReadLocked()796     public void testWriteTryLockWhenReadLocked()      { testWriteTryLockWhenReadLocked(false); }
testWriteTryLockWhenReadLocked_fair()797     public void testWriteTryLockWhenReadLocked_fair() { testWriteTryLockWhenReadLocked(true); }
testWriteTryLockWhenReadLocked(boolean fair)798     public void testWriteTryLockWhenReadLocked(boolean fair) {
799         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
800         lock.readLock().lock();
801         Thread t = newStartedThread(new CheckedRunnable() {
802             public void realRun() {
803                 assertFalse(lock.writeLock().tryLock());
804             }});
805 
806         awaitTermination(t);
807         lock.readLock().unlock();
808     }
809 
810     /**
811      * write timed tryLock times out if locked
812      */
testWriteTryLock_Timeout()813     public void testWriteTryLock_Timeout()      { testWriteTryLock_Timeout(false); }
testWriteTryLock_Timeout_fair()814     public void testWriteTryLock_Timeout_fair() { testWriteTryLock_Timeout(true); }
testWriteTryLock_Timeout(boolean fair)815     public void testWriteTryLock_Timeout(boolean fair) {
816         final PublicReentrantReadWriteLock lock =
817             new PublicReentrantReadWriteLock(fair);
818         final long timeoutMillis = timeoutMillis();
819         lock.writeLock().lock();
820         Thread t = newStartedThread(new CheckedRunnable() {
821             public void realRun() throws InterruptedException {
822                 long startTime = System.nanoTime();
823                 assertFalse(lock.writeLock().tryLock(timeoutMillis, MILLISECONDS));
824                 assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
825             }});
826 
827         awaitTermination(t);
828         releaseWriteLock(lock);
829     }
830 
831     /**
832      * read timed tryLock times out if write-locked
833      */
testReadTryLock_Timeout()834     public void testReadTryLock_Timeout()      { testReadTryLock_Timeout(false); }
testReadTryLock_Timeout_fair()835     public void testReadTryLock_Timeout_fair() { testReadTryLock_Timeout(true); }
testReadTryLock_Timeout(boolean fair)836     public void testReadTryLock_Timeout(boolean fair) {
837         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
838         lock.writeLock().lock();
839         Thread t = newStartedThread(new CheckedRunnable() {
840             public void realRun() throws InterruptedException {
841                 long startTime = System.nanoTime();
842                 long timeoutMillis = timeoutMillis();
843                 assertFalse(lock.readLock().tryLock(timeoutMillis, MILLISECONDS));
844                 assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
845             }});
846 
847         awaitTermination(t);
848         assertTrue(lock.writeLock().isHeldByCurrentThread());
849         lock.writeLock().unlock();
850     }
851 
852     /**
853      * write lockInterruptibly succeeds if unlocked, else is interruptible
854      */
testWriteLockInterruptibly()855     public void testWriteLockInterruptibly()      { testWriteLockInterruptibly(false); }
testWriteLockInterruptibly_fair()856     public void testWriteLockInterruptibly_fair() { testWriteLockInterruptibly(true); }
testWriteLockInterruptibly(boolean fair)857     public void testWriteLockInterruptibly(boolean fair) {
858         final PublicReentrantReadWriteLock lock =
859             new PublicReentrantReadWriteLock(fair);
860         try {
861             lock.writeLock().lockInterruptibly();
862         } catch (InterruptedException fail) { threadUnexpectedException(fail); }
863         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
864             public void realRun() throws InterruptedException {
865                 lock.writeLock().lockInterruptibly();
866             }});
867 
868         waitForQueuedThread(lock, t);
869         t.interrupt();
870         assertTrue(lock.writeLock().isHeldByCurrentThread());
871         awaitTermination(t);
872         releaseWriteLock(lock);
873     }
874 
875     /**
876      * read lockInterruptibly succeeds if lock free else is interruptible
877      */
testReadLockInterruptibly()878     public void testReadLockInterruptibly()      { testReadLockInterruptibly(false); }
testReadLockInterruptibly_fair()879     public void testReadLockInterruptibly_fair() { testReadLockInterruptibly(true); }
testReadLockInterruptibly(boolean fair)880     public void testReadLockInterruptibly(boolean fair) {
881         final PublicReentrantReadWriteLock lock =
882             new PublicReentrantReadWriteLock(fair);
883         try {
884             lock.readLock().lockInterruptibly();
885             lock.readLock().unlock();
886             lock.writeLock().lockInterruptibly();
887         } catch (InterruptedException fail) { threadUnexpectedException(fail); }
888         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
889             public void realRun() throws InterruptedException {
890                 lock.readLock().lockInterruptibly();
891             }});
892 
893         waitForQueuedThread(lock, t);
894         t.interrupt();
895         awaitTermination(t);
896         releaseWriteLock(lock);
897     }
898 
899     /**
900      * Calling await without holding lock throws IllegalMonitorStateException
901      */
testAwait_IMSE()902     public void testAwait_IMSE()      { testAwait_IMSE(false); }
testAwait_IMSE_fair()903     public void testAwait_IMSE_fair() { testAwait_IMSE(true); }
testAwait_IMSE(boolean fair)904     public void testAwait_IMSE(boolean fair) {
905         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
906         final Condition c = lock.writeLock().newCondition();
907         for (AwaitMethod awaitMethod : AwaitMethod.values()) {
908             long startTime = System.nanoTime();
909             try {
910                 await(c, awaitMethod);
911                 shouldThrow();
912             } catch (IllegalMonitorStateException success) {
913             } catch (InterruptedException fail) {
914                 threadUnexpectedException(fail);
915             }
916             assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
917         }
918     }
919 
920     /**
921      * Calling signal without holding lock throws IllegalMonitorStateException
922      */
923     public void testSignal_IMSE()      { testSignal_IMSE(false); }
924     public void testSignal_IMSE_fair() { testSignal_IMSE(true); }
925     public void testSignal_IMSE(boolean fair) {
926         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
927         final Condition c = lock.writeLock().newCondition();
928         try {
929             c.signal();
930             shouldThrow();
931         } catch (IllegalMonitorStateException success) {}
932     }
933 
934     /**
935      * Calling signalAll without holding lock throws IllegalMonitorStateException
936      */
937     public void testSignalAll_IMSE()      { testSignalAll_IMSE(false); }
938     public void testSignalAll_IMSE_fair() { testSignalAll_IMSE(true); }
939     public void testSignalAll_IMSE(boolean fair) {
940         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
941         final Condition c = lock.writeLock().newCondition();
942         try {
943             c.signalAll();
944             shouldThrow();
945         } catch (IllegalMonitorStateException success) {}
946     }
947 
948     /**
949      * awaitNanos without a signal times out
950      */
951     public void testAwaitNanos_Timeout()      { testAwaitNanos_Timeout(false); }
952     public void testAwaitNanos_Timeout_fair() { testAwaitNanos_Timeout(true); }
953     public void testAwaitNanos_Timeout(boolean fair) {
954         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
955         final Condition c = lock.writeLock().newCondition();
956         final long timeoutMillis = timeoutMillis();
957         lock.writeLock().lock();
958         final long startTime = System.nanoTime();
959         final long timeoutNanos = MILLISECONDS.toNanos(timeoutMillis);
960         try {
961             long nanosRemaining = c.awaitNanos(timeoutNanos);
962             assertTrue(nanosRemaining <= 0);
963         } catch (InterruptedException fail) { threadUnexpectedException(fail); }
964         assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
965         lock.writeLock().unlock();
966     }
967 
968     /**
969      * timed await without a signal times out
970      */
971     public void testAwait_Timeout()      { testAwait_Timeout(false); }
972     public void testAwait_Timeout_fair() { testAwait_Timeout(true); }
973     public void testAwait_Timeout(boolean fair) {
974         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
975         final Condition c = lock.writeLock().newCondition();
976         final long timeoutMillis = timeoutMillis();
977         lock.writeLock().lock();
978         final long startTime = System.nanoTime();
979         try {
980             assertFalse(c.await(timeoutMillis, MILLISECONDS));
981         } catch (InterruptedException fail) { threadUnexpectedException(fail); }
982         assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
983         lock.writeLock().unlock();
984     }
985 
986     /**
987      * awaitUntil without a signal times out
988      */
testAwaitUntil_Timeout()989     public void testAwaitUntil_Timeout()      { testAwaitUntil_Timeout(false); }
testAwaitUntil_Timeout_fair()990     public void testAwaitUntil_Timeout_fair() { testAwaitUntil_Timeout(true); }
testAwaitUntil_Timeout(boolean fair)991     public void testAwaitUntil_Timeout(boolean fair) {
992         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
993         final Condition c = lock.writeLock().newCondition();
994         lock.writeLock().lock();
995         // We shouldn't assume that nanoTime and currentTimeMillis
996         // use the same time source, so don't use nanoTime here.
997         final java.util.Date delayedDate = delayedDate(timeoutMillis());
998         try {
999             assertFalse(c.awaitUntil(delayedDate));
1000         } catch (InterruptedException fail) { threadUnexpectedException(fail); }
1001         assertTrue(new java.util.Date().getTime() >= delayedDate.getTime());
1002         lock.writeLock().unlock();
1003     }
1004 
1005     /**
1006      * await returns when signalled
1007      */
testAwait()1008     public void testAwait()      { testAwait(false); }
testAwait_fair()1009     public void testAwait_fair() { testAwait(true); }
testAwait(boolean fair)1010     public void testAwait(boolean fair) {
1011         final PublicReentrantReadWriteLock lock =
1012             new PublicReentrantReadWriteLock(fair);
1013         final Condition c = lock.writeLock().newCondition();
1014         final CountDownLatch locked = new CountDownLatch(1);
1015         Thread t = newStartedThread(new CheckedRunnable() {
1016             public void realRun() throws InterruptedException {
1017                 lock.writeLock().lock();
1018                 locked.countDown();
1019                 c.await();
1020                 lock.writeLock().unlock();
1021             }});
1022 
1023         await(locked);
1024         lock.writeLock().lock();
1025         assertHasWaiters(lock, c, t);
1026         c.signal();
1027         assertHasNoWaiters(lock, c);
1028         assertTrue(t.isAlive());
1029         lock.writeLock().unlock();
1030         awaitTermination(t);
1031     }
1032 
1033     /**
1034      * awaitUninterruptibly is uninterruptible
1035      */
testAwaitUninterruptibly()1036     public void testAwaitUninterruptibly()      { testAwaitUninterruptibly(false); }
testAwaitUninterruptibly_fair()1037     public void testAwaitUninterruptibly_fair() { testAwaitUninterruptibly(true); }
testAwaitUninterruptibly(boolean fair)1038     public void testAwaitUninterruptibly(boolean fair) {
1039         final Lock lock = new ReentrantReadWriteLock(fair).writeLock();
1040         final Condition condition = lock.newCondition();
1041         final CountDownLatch pleaseInterrupt = new CountDownLatch(2);
1042 
1043         Thread t1 = newStartedThread(new CheckedRunnable() {
1044             public void realRun() {
1045                 // Interrupt before awaitUninterruptibly
1046                 lock.lock();
1047                 pleaseInterrupt.countDown();
1048                 Thread.currentThread().interrupt();
1049                 condition.awaitUninterruptibly();
1050                 assertTrue(Thread.interrupted());
1051                 lock.unlock();
1052             }});
1053 
1054         Thread t2 = newStartedThread(new CheckedRunnable() {
1055             public void realRun() {
1056                 // Interrupt during awaitUninterruptibly
1057                 lock.lock();
1058                 pleaseInterrupt.countDown();
1059                 condition.awaitUninterruptibly();
1060                 assertTrue(Thread.interrupted());
1061                 lock.unlock();
1062             }});
1063 
1064         await(pleaseInterrupt);
1065         t2.interrupt();
1066         lock.lock();
1067         lock.unlock();
1068         assertThreadBlocks(t1, Thread.State.WAITING);
1069         assertThreadBlocks(t2, Thread.State.WAITING);
1070 
1071         lock.lock();
1072         condition.signalAll();
1073         lock.unlock();
1074 
1075         awaitTermination(t1);
1076         awaitTermination(t2);
1077     }
1078 
1079     /**
1080      * await/awaitNanos/awaitUntil is interruptible
1081      */
testInterruptible_await()1082     public void testInterruptible_await()           { testInterruptible(false, AwaitMethod.await); }
testInterruptible_await_fair()1083     public void testInterruptible_await_fair()      { testInterruptible(true,  AwaitMethod.await); }
testInterruptible_awaitTimed()1084     public void testInterruptible_awaitTimed()      { testInterruptible(false, AwaitMethod.awaitTimed); }
testInterruptible_awaitTimed_fair()1085     public void testInterruptible_awaitTimed_fair() { testInterruptible(true,  AwaitMethod.awaitTimed); }
testInterruptible_awaitNanos()1086     public void testInterruptible_awaitNanos()      { testInterruptible(false, AwaitMethod.awaitNanos); }
testInterruptible_awaitNanos_fair()1087     public void testInterruptible_awaitNanos_fair() { testInterruptible(true,  AwaitMethod.awaitNanos); }
testInterruptible_awaitUntil()1088     public void testInterruptible_awaitUntil()      { testInterruptible(false, AwaitMethod.awaitUntil); }
testInterruptible_awaitUntil_fair()1089     public void testInterruptible_awaitUntil_fair() { testInterruptible(true,  AwaitMethod.awaitUntil); }
testInterruptible(boolean fair, final AwaitMethod awaitMethod)1090     public void testInterruptible(boolean fair, final AwaitMethod awaitMethod) {
1091         final PublicReentrantReadWriteLock lock =
1092             new PublicReentrantReadWriteLock(fair);
1093         final Condition c = lock.writeLock().newCondition();
1094         final CountDownLatch locked = new CountDownLatch(1);
1095         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
1096             public void realRun() throws InterruptedException {
1097                 lock.writeLock().lock();
1098                 assertWriteLockedByMoi(lock);
1099                 assertHasNoWaiters(lock, c);
1100                 locked.countDown();
1101                 try {
1102                     await(c, awaitMethod);
1103                 } finally {
1104                     assertWriteLockedByMoi(lock);
1105                     assertHasNoWaiters(lock, c);
1106                     lock.writeLock().unlock();
1107                     assertFalse(Thread.interrupted());
1108                 }
1109             }});
1110 
1111         await(locked);
1112         assertHasWaiters(lock, c, t);
1113         t.interrupt();
1114         awaitTermination(t);
1115         assertNotWriteLocked(lock);
1116     }
1117 
1118     /**
1119      * signalAll wakes up all threads
1120      */
testSignalAll_await()1121     public void testSignalAll_await()           { testSignalAll(false, AwaitMethod.await); }
testSignalAll_await_fair()1122     public void testSignalAll_await_fair()      { testSignalAll(true,  AwaitMethod.await); }
testSignalAll_awaitTimed()1123     public void testSignalAll_awaitTimed()      { testSignalAll(false, AwaitMethod.awaitTimed); }
testSignalAll_awaitTimed_fair()1124     public void testSignalAll_awaitTimed_fair() { testSignalAll(true,  AwaitMethod.awaitTimed); }
testSignalAll_awaitNanos()1125     public void testSignalAll_awaitNanos()      { testSignalAll(false, AwaitMethod.awaitNanos); }
testSignalAll_awaitNanos_fair()1126     public void testSignalAll_awaitNanos_fair() { testSignalAll(true,  AwaitMethod.awaitNanos); }
testSignalAll_awaitUntil()1127     public void testSignalAll_awaitUntil()      { testSignalAll(false, AwaitMethod.awaitUntil); }
testSignalAll_awaitUntil_fair()1128     public void testSignalAll_awaitUntil_fair() { testSignalAll(true,  AwaitMethod.awaitUntil); }
testSignalAll(boolean fair, final AwaitMethod awaitMethod)1129     public void testSignalAll(boolean fair, final AwaitMethod awaitMethod) {
1130         final PublicReentrantReadWriteLock lock =
1131             new PublicReentrantReadWriteLock(fair);
1132         final Condition c = lock.writeLock().newCondition();
1133         final CountDownLatch locked = new CountDownLatch(2);
1134         final Lock writeLock = lock.writeLock();
1135         class Awaiter extends CheckedRunnable {
1136             public void realRun() throws InterruptedException {
1137                 writeLock.lock();
1138                 locked.countDown();
1139                 await(c, awaitMethod);
1140                 writeLock.unlock();
1141             }
1142         }
1143 
1144         Thread t1 = newStartedThread(new Awaiter());
1145         Thread t2 = newStartedThread(new Awaiter());
1146 
1147         await(locked);
1148         writeLock.lock();
1149         assertHasWaiters(lock, c, t1, t2);
1150         c.signalAll();
1151         assertHasNoWaiters(lock, c);
1152         writeLock.unlock();
1153         awaitTermination(t1);
1154         awaitTermination(t2);
1155     }
1156 
1157     /**
1158      * signal wakes up waiting threads in FIFO order
1159      */
testSignalWakesFifo()1160     public void testSignalWakesFifo()      { testSignalWakesFifo(false); }
testSignalWakesFifo_fair()1161     public void testSignalWakesFifo_fair() { testSignalWakesFifo(true); }
testSignalWakesFifo(boolean fair)1162     public void testSignalWakesFifo(boolean fair) {
1163         final PublicReentrantReadWriteLock lock =
1164             new PublicReentrantReadWriteLock(fair);
1165         final Condition c = lock.writeLock().newCondition();
1166         final CountDownLatch locked1 = new CountDownLatch(1);
1167         final CountDownLatch locked2 = new CountDownLatch(1);
1168         final Lock writeLock = lock.writeLock();
1169         Thread t1 = newStartedThread(new CheckedRunnable() {
1170             public void realRun() throws InterruptedException {
1171                 writeLock.lock();
1172                 locked1.countDown();
1173                 c.await();
1174                 writeLock.unlock();
1175             }});
1176 
1177         await(locked1);
1178 
1179         Thread t2 = newStartedThread(new CheckedRunnable() {
1180             public void realRun() throws InterruptedException {
1181                 writeLock.lock();
1182                 locked2.countDown();
1183                 c.await();
1184                 writeLock.unlock();
1185             }});
1186 
1187         await(locked2);
1188 
1189         writeLock.lock();
1190         assertHasWaiters(lock, c, t1, t2);
1191         assertFalse(lock.hasQueuedThreads());
1192         c.signal();
1193         assertHasWaiters(lock, c, t2);
1194         assertTrue(lock.hasQueuedThread(t1));
1195         assertFalse(lock.hasQueuedThread(t2));
1196         c.signal();
1197         assertHasNoWaiters(lock, c);
1198         assertTrue(lock.hasQueuedThread(t1));
1199         assertTrue(lock.hasQueuedThread(t2));
1200         writeLock.unlock();
1201         awaitTermination(t1);
1202         awaitTermination(t2);
1203     }
1204 
1205     /**
1206      * await after multiple reentrant locking preserves lock count
1207      */
testAwaitLockCount()1208     public void testAwaitLockCount()      { testAwaitLockCount(false); }
testAwaitLockCount_fair()1209     public void testAwaitLockCount_fair() { testAwaitLockCount(true); }
testAwaitLockCount(boolean fair)1210     public void testAwaitLockCount(boolean fair) {
1211         final PublicReentrantReadWriteLock lock =
1212             new PublicReentrantReadWriteLock(fair);
1213         final Condition c = lock.writeLock().newCondition();
1214         final CountDownLatch locked = new CountDownLatch(2);
1215         Thread t1 = newStartedThread(new CheckedRunnable() {
1216             public void realRun() throws InterruptedException {
1217                 lock.writeLock().lock();
1218                 assertWriteLockedByMoi(lock);
1219                 assertEquals(1, lock.writeLock().getHoldCount());
1220                 locked.countDown();
1221                 c.await();
1222                 assertWriteLockedByMoi(lock);
1223                 assertEquals(1, lock.writeLock().getHoldCount());
1224                 lock.writeLock().unlock();
1225             }});
1226 
1227         Thread t2 = newStartedThread(new CheckedRunnable() {
1228             public void realRun() throws InterruptedException {
1229                 lock.writeLock().lock();
1230                 lock.writeLock().lock();
1231                 assertWriteLockedByMoi(lock);
1232                 assertEquals(2, lock.writeLock().getHoldCount());
1233                 locked.countDown();
1234                 c.await();
1235                 assertWriteLockedByMoi(lock);
1236                 assertEquals(2, lock.writeLock().getHoldCount());
1237                 lock.writeLock().unlock();
1238                 lock.writeLock().unlock();
1239             }});
1240 
1241         await(locked);
1242         lock.writeLock().lock();
1243         assertHasWaiters(lock, c, t1, t2);
1244         c.signalAll();
1245         assertHasNoWaiters(lock, c);
1246         lock.writeLock().unlock();
1247         awaitTermination(t1);
1248         awaitTermination(t2);
1249     }
1250 
1251     /**
1252      * A serialized lock deserializes as unlocked
1253      */
testSerialization()1254     public void testSerialization()      { testSerialization(false); }
testSerialization_fair()1255     public void testSerialization_fair() { testSerialization(true); }
testSerialization(boolean fair)1256     public void testSerialization(boolean fair) {
1257         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1258         lock.writeLock().lock();
1259         lock.readLock().lock();
1260 
1261         ReentrantReadWriteLock clone = serialClone(lock);
1262         assertEquals(lock.isFair(), clone.isFair());
1263         assertTrue(lock.isWriteLocked());
1264         assertFalse(clone.isWriteLocked());
1265         assertEquals(1, lock.getReadLockCount());
1266         assertEquals(0, clone.getReadLockCount());
1267         clone.writeLock().lock();
1268         clone.readLock().lock();
1269         assertTrue(clone.isWriteLocked());
1270         assertEquals(1, clone.getReadLockCount());
1271         clone.readLock().unlock();
1272         clone.writeLock().unlock();
1273         assertFalse(clone.isWriteLocked());
1274         assertEquals(1, lock.getReadLockCount());
1275         assertEquals(0, clone.getReadLockCount());
1276     }
1277 
1278     /**
1279      * hasQueuedThreads reports whether there are waiting threads
1280      */
testHasQueuedThreads()1281     public void testHasQueuedThreads()      { testHasQueuedThreads(false); }
testHasQueuedThreads_fair()1282     public void testHasQueuedThreads_fair() { testHasQueuedThreads(true); }
testHasQueuedThreads(boolean fair)1283     public void testHasQueuedThreads(boolean fair) {
1284         final PublicReentrantReadWriteLock lock =
1285             new PublicReentrantReadWriteLock(fair);
1286         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1287         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1288         assertFalse(lock.hasQueuedThreads());
1289         lock.writeLock().lock();
1290         assertFalse(lock.hasQueuedThreads());
1291         t1.start();
1292         waitForQueuedThread(lock, t1);
1293         assertTrue(lock.hasQueuedThreads());
1294         t2.start();
1295         waitForQueuedThread(lock, t2);
1296         assertTrue(lock.hasQueuedThreads());
1297         t1.interrupt();
1298         awaitTermination(t1);
1299         assertTrue(lock.hasQueuedThreads());
1300         lock.writeLock().unlock();
1301         awaitTermination(t2);
1302         assertFalse(lock.hasQueuedThreads());
1303     }
1304 
1305     /**
1306      * hasQueuedThread(null) throws NPE
1307      */
testHasQueuedThreadNPE()1308     public void testHasQueuedThreadNPE()      { testHasQueuedThreadNPE(false); }
testHasQueuedThreadNPE_fair()1309     public void testHasQueuedThreadNPE_fair() { testHasQueuedThreadNPE(true); }
testHasQueuedThreadNPE(boolean fair)1310     public void testHasQueuedThreadNPE(boolean fair) {
1311         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1312         try {
1313             lock.hasQueuedThread(null);
1314             shouldThrow();
1315         } catch (NullPointerException success) {}
1316     }
1317 
1318     /**
1319      * hasQueuedThread reports whether a thread is queued
1320      */
testHasQueuedThread()1321     public void testHasQueuedThread()      { testHasQueuedThread(false); }
testHasQueuedThread_fair()1322     public void testHasQueuedThread_fair() { testHasQueuedThread(true); }
testHasQueuedThread(boolean fair)1323     public void testHasQueuedThread(boolean fair) {
1324         final PublicReentrantReadWriteLock lock =
1325             new PublicReentrantReadWriteLock(fair);
1326         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1327         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1328         assertFalse(lock.hasQueuedThread(t1));
1329         assertFalse(lock.hasQueuedThread(t2));
1330         lock.writeLock().lock();
1331         t1.start();
1332         waitForQueuedThread(lock, t1);
1333         assertTrue(lock.hasQueuedThread(t1));
1334         assertFalse(lock.hasQueuedThread(t2));
1335         t2.start();
1336         waitForQueuedThread(lock, t2);
1337         assertTrue(lock.hasQueuedThread(t1));
1338         assertTrue(lock.hasQueuedThread(t2));
1339         t1.interrupt();
1340         awaitTermination(t1);
1341         assertFalse(lock.hasQueuedThread(t1));
1342         assertTrue(lock.hasQueuedThread(t2));
1343         lock.writeLock().unlock();
1344         awaitTermination(t2);
1345         assertFalse(lock.hasQueuedThread(t1));
1346         assertFalse(lock.hasQueuedThread(t2));
1347     }
1348 
1349     /**
1350      * getQueueLength reports number of waiting threads
1351      */
testGetQueueLength()1352     public void testGetQueueLength()      { testGetQueueLength(false); }
testGetQueueLength_fair()1353     public void testGetQueueLength_fair() { testGetQueueLength(true); }
testGetQueueLength(boolean fair)1354     public void testGetQueueLength(boolean fair) {
1355         final PublicReentrantReadWriteLock lock =
1356             new PublicReentrantReadWriteLock(fair);
1357         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1358         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1359         assertEquals(0, lock.getQueueLength());
1360         lock.writeLock().lock();
1361         t1.start();
1362         waitForQueuedThread(lock, t1);
1363         assertEquals(1, lock.getQueueLength());
1364         t2.start();
1365         waitForQueuedThread(lock, t2);
1366         assertEquals(2, lock.getQueueLength());
1367         t1.interrupt();
1368         awaitTermination(t1);
1369         assertEquals(1, lock.getQueueLength());
1370         lock.writeLock().unlock();
1371         awaitTermination(t2);
1372         assertEquals(0, lock.getQueueLength());
1373     }
1374 
1375     /**
1376      * getQueuedThreads includes waiting threads
1377      */
testGetQueuedThreads()1378     public void testGetQueuedThreads()      { testGetQueuedThreads(false); }
testGetQueuedThreads_fair()1379     public void testGetQueuedThreads_fair() { testGetQueuedThreads(true); }
testGetQueuedThreads(boolean fair)1380     public void testGetQueuedThreads(boolean fair) {
1381         final PublicReentrantReadWriteLock lock =
1382             new PublicReentrantReadWriteLock(fair);
1383         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1384         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1385         assertTrue(lock.getQueuedThreads().isEmpty());
1386         lock.writeLock().lock();
1387         assertTrue(lock.getQueuedThreads().isEmpty());
1388         t1.start();
1389         waitForQueuedThread(lock, t1);
1390         assertEquals(1, lock.getQueuedThreads().size());
1391         assertTrue(lock.getQueuedThreads().contains(t1));
1392         t2.start();
1393         waitForQueuedThread(lock, t2);
1394         assertEquals(2, lock.getQueuedThreads().size());
1395         assertTrue(lock.getQueuedThreads().contains(t1));
1396         assertTrue(lock.getQueuedThreads().contains(t2));
1397         t1.interrupt();
1398         awaitTermination(t1);
1399         assertFalse(lock.getQueuedThreads().contains(t1));
1400         assertTrue(lock.getQueuedThreads().contains(t2));
1401         assertEquals(1, lock.getQueuedThreads().size());
1402         lock.writeLock().unlock();
1403         awaitTermination(t2);
1404         assertTrue(lock.getQueuedThreads().isEmpty());
1405     }
1406 
1407     /**
1408      * hasWaiters throws NPE if null
1409      */
testHasWaitersNPE()1410     public void testHasWaitersNPE()      { testHasWaitersNPE(false); }
testHasWaitersNPE_fair()1411     public void testHasWaitersNPE_fair() { testHasWaitersNPE(true); }
testHasWaitersNPE(boolean fair)1412     public void testHasWaitersNPE(boolean fair) {
1413         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1414         try {
1415             lock.hasWaiters(null);
1416             shouldThrow();
1417         } catch (NullPointerException success) {}
1418     }
1419 
1420     /**
1421      * getWaitQueueLength throws NPE if null
1422      */
testGetWaitQueueLengthNPE()1423     public void testGetWaitQueueLengthNPE()      { testGetWaitQueueLengthNPE(false); }
testGetWaitQueueLengthNPE_fair()1424     public void testGetWaitQueueLengthNPE_fair() { testGetWaitQueueLengthNPE(true); }
testGetWaitQueueLengthNPE(boolean fair)1425     public void testGetWaitQueueLengthNPE(boolean fair) {
1426         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1427         try {
1428             lock.getWaitQueueLength(null);
1429             shouldThrow();
1430         } catch (NullPointerException success) {}
1431     }
1432 
1433     /**
1434      * getWaitingThreads throws NPE if null
1435      */
testGetWaitingThreadsNPE()1436     public void testGetWaitingThreadsNPE()      { testGetWaitingThreadsNPE(false); }
testGetWaitingThreadsNPE_fair()1437     public void testGetWaitingThreadsNPE_fair() { testGetWaitingThreadsNPE(true); }
testGetWaitingThreadsNPE(boolean fair)1438     public void testGetWaitingThreadsNPE(boolean fair) {
1439         final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock(fair);
1440         try {
1441             lock.getWaitingThreads(null);
1442             shouldThrow();
1443         } catch (NullPointerException success) {}
1444     }
1445 
1446     /**
1447      * hasWaiters throws IllegalArgumentException if not owned
1448      */
testHasWaitersIAE()1449     public void testHasWaitersIAE()      { testHasWaitersIAE(false); }
testHasWaitersIAE_fair()1450     public void testHasWaitersIAE_fair() { testHasWaitersIAE(true); }
testHasWaitersIAE(boolean fair)1451     public void testHasWaitersIAE(boolean fair) {
1452         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1453         final Condition c = lock.writeLock().newCondition();
1454         final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock(fair);
1455         try {
1456             lock2.hasWaiters(c);
1457             shouldThrow();
1458         } catch (IllegalArgumentException success) {}
1459     }
1460 
1461     /**
1462      * hasWaiters throws IllegalMonitorStateException if not locked
1463      */
testHasWaitersIMSE()1464     public void testHasWaitersIMSE()      { testHasWaitersIMSE(false); }
testHasWaitersIMSE_fair()1465     public void testHasWaitersIMSE_fair() { testHasWaitersIMSE(true); }
testHasWaitersIMSE(boolean fair)1466     public void testHasWaitersIMSE(boolean fair) {
1467         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1468         final Condition c = lock.writeLock().newCondition();
1469         try {
1470             lock.hasWaiters(c);
1471             shouldThrow();
1472         } catch (IllegalMonitorStateException success) {}
1473     }
1474 
1475     /**
1476      * getWaitQueueLength throws IllegalArgumentException if not owned
1477      */
testGetWaitQueueLengthIAE()1478     public void testGetWaitQueueLengthIAE()      { testGetWaitQueueLengthIAE(false); }
testGetWaitQueueLengthIAE_fair()1479     public void testGetWaitQueueLengthIAE_fair() { testGetWaitQueueLengthIAE(true); }
testGetWaitQueueLengthIAE(boolean fair)1480     public void testGetWaitQueueLengthIAE(boolean fair) {
1481         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1482         final Condition c = lock.writeLock().newCondition();
1483         final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock(fair);
1484         try {
1485             lock2.getWaitQueueLength(c);
1486             shouldThrow();
1487         } catch (IllegalArgumentException success) {}
1488     }
1489 
1490     /**
1491      * getWaitQueueLength throws IllegalMonitorStateException if not locked
1492      */
testGetWaitQueueLengthIMSE()1493     public void testGetWaitQueueLengthIMSE()      { testGetWaitQueueLengthIMSE(false); }
testGetWaitQueueLengthIMSE_fair()1494     public void testGetWaitQueueLengthIMSE_fair() { testGetWaitQueueLengthIMSE(true); }
testGetWaitQueueLengthIMSE(boolean fair)1495     public void testGetWaitQueueLengthIMSE(boolean fair) {
1496         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1497         final Condition c = lock.writeLock().newCondition();
1498         try {
1499             lock.getWaitQueueLength(c);
1500             shouldThrow();
1501         } catch (IllegalMonitorStateException success) {}
1502     }
1503 
1504     /**
1505      * getWaitingThreads throws IllegalArgumentException if not owned
1506      */
testGetWaitingThreadsIAE()1507     public void testGetWaitingThreadsIAE()      { testGetWaitingThreadsIAE(false); }
testGetWaitingThreadsIAE_fair()1508     public void testGetWaitingThreadsIAE_fair() { testGetWaitingThreadsIAE(true); }
testGetWaitingThreadsIAE(boolean fair)1509     public void testGetWaitingThreadsIAE(boolean fair) {
1510         final PublicReentrantReadWriteLock lock =
1511             new PublicReentrantReadWriteLock(fair);
1512         final Condition c = lock.writeLock().newCondition();
1513         final PublicReentrantReadWriteLock lock2 =
1514             new PublicReentrantReadWriteLock(fair);
1515         try {
1516             lock2.getWaitingThreads(c);
1517             shouldThrow();
1518         } catch (IllegalArgumentException success) {}
1519     }
1520 
1521     /**
1522      * getWaitingThreads throws IllegalMonitorStateException if not locked
1523      */
testGetWaitingThreadsIMSE()1524     public void testGetWaitingThreadsIMSE()      { testGetWaitingThreadsIMSE(false); }
testGetWaitingThreadsIMSE_fair()1525     public void testGetWaitingThreadsIMSE_fair() { testGetWaitingThreadsIMSE(true); }
testGetWaitingThreadsIMSE(boolean fair)1526     public void testGetWaitingThreadsIMSE(boolean fair) {
1527         final PublicReentrantReadWriteLock lock =
1528             new PublicReentrantReadWriteLock(fair);
1529         final Condition c = lock.writeLock().newCondition();
1530         try {
1531             lock.getWaitingThreads(c);
1532             shouldThrow();
1533         } catch (IllegalMonitorStateException success) {}
1534     }
1535 
1536     /**
1537      * hasWaiters returns true when a thread is waiting, else false
1538      */
testHasWaiters()1539     public void testHasWaiters()      { testHasWaiters(false); }
testHasWaiters_fair()1540     public void testHasWaiters_fair() { testHasWaiters(true); }
testHasWaiters(boolean fair)1541     public void testHasWaiters(boolean fair) {
1542         final PublicReentrantReadWriteLock lock =
1543             new PublicReentrantReadWriteLock(fair);
1544         final Condition c = lock.writeLock().newCondition();
1545         final CountDownLatch locked = new CountDownLatch(1);
1546         Thread t = newStartedThread(new CheckedRunnable() {
1547             public void realRun() throws InterruptedException {
1548                 lock.writeLock().lock();
1549                 assertHasNoWaiters(lock, c);
1550                 assertFalse(lock.hasWaiters(c));
1551                 locked.countDown();
1552                 c.await();
1553                 assertHasNoWaiters(lock, c);
1554                 assertFalse(lock.hasWaiters(c));
1555                 lock.writeLock().unlock();
1556             }});
1557 
1558         await(locked);
1559         lock.writeLock().lock();
1560         assertHasWaiters(lock, c, t);
1561         assertTrue(lock.hasWaiters(c));
1562         c.signal();
1563         assertHasNoWaiters(lock, c);
1564         assertFalse(lock.hasWaiters(c));
1565         lock.writeLock().unlock();
1566         awaitTermination(t);
1567         assertHasNoWaiters(lock, c);
1568     }
1569 
1570     /**
1571      * getWaitQueueLength returns number of waiting threads
1572      */
testGetWaitQueueLength()1573     public void testGetWaitQueueLength()      { testGetWaitQueueLength(false); }
testGetWaitQueueLength_fair()1574     public void testGetWaitQueueLength_fair() { testGetWaitQueueLength(true); }
testGetWaitQueueLength(boolean fair)1575     public void testGetWaitQueueLength(boolean fair) {
1576         final PublicReentrantReadWriteLock lock =
1577             new PublicReentrantReadWriteLock(fair);
1578         final Condition c = lock.writeLock().newCondition();
1579         final CountDownLatch locked = new CountDownLatch(1);
1580         Thread t = newStartedThread(new CheckedRunnable() {
1581             public void realRun() throws InterruptedException {
1582                 lock.writeLock().lock();
1583                 assertEquals(0, lock.getWaitQueueLength(c));
1584                 locked.countDown();
1585                 c.await();
1586                 lock.writeLock().unlock();
1587             }});
1588 
1589         await(locked);
1590         lock.writeLock().lock();
1591         assertHasWaiters(lock, c, t);
1592         assertEquals(1, lock.getWaitQueueLength(c));
1593         c.signal();
1594         assertHasNoWaiters(lock, c);
1595         assertEquals(0, lock.getWaitQueueLength(c));
1596         lock.writeLock().unlock();
1597         awaitTermination(t);
1598     }
1599 
1600     /**
1601      * getWaitingThreads returns only and all waiting threads
1602      */
testGetWaitingThreads()1603     public void testGetWaitingThreads()      { testGetWaitingThreads(false); }
testGetWaitingThreads_fair()1604     public void testGetWaitingThreads_fair() { testGetWaitingThreads(true); }
testGetWaitingThreads(boolean fair)1605     public void testGetWaitingThreads(boolean fair) {
1606         final PublicReentrantReadWriteLock lock =
1607             new PublicReentrantReadWriteLock(fair);
1608         final Condition c = lock.writeLock().newCondition();
1609         final CountDownLatch locked1 = new CountDownLatch(1);
1610         final CountDownLatch locked2 = new CountDownLatch(1);
1611         Thread t1 = new Thread(new CheckedRunnable() {
1612             public void realRun() throws InterruptedException {
1613                 lock.writeLock().lock();
1614                 assertTrue(lock.getWaitingThreads(c).isEmpty());
1615                 locked1.countDown();
1616                 c.await();
1617                 lock.writeLock().unlock();
1618             }});
1619 
1620         Thread t2 = new Thread(new CheckedRunnable() {
1621             public void realRun() throws InterruptedException {
1622                 lock.writeLock().lock();
1623                 assertFalse(lock.getWaitingThreads(c).isEmpty());
1624                 locked2.countDown();
1625                 c.await();
1626                 lock.writeLock().unlock();
1627             }});
1628 
1629         lock.writeLock().lock();
1630         assertTrue(lock.getWaitingThreads(c).isEmpty());
1631         lock.writeLock().unlock();
1632 
1633         t1.start();
1634         await(locked1);
1635         t2.start();
1636         await(locked2);
1637 
1638         lock.writeLock().lock();
1639         assertTrue(lock.hasWaiters(c));
1640         assertTrue(lock.getWaitingThreads(c).contains(t1));
1641         assertTrue(lock.getWaitingThreads(c).contains(t2));
1642         assertEquals(2, lock.getWaitingThreads(c).size());
1643         c.signalAll();
1644         assertHasNoWaiters(lock, c);
1645         lock.writeLock().unlock();
1646 
1647         awaitTermination(t1);
1648         awaitTermination(t2);
1649 
1650         assertHasNoWaiters(lock, c);
1651     }
1652 
1653     /**
1654      * toString indicates current lock state
1655      */
testToString()1656     public void testToString()      { testToString(false); }
testToString_fair()1657     public void testToString_fair() { testToString(true); }
testToString(boolean fair)1658     public void testToString(boolean fair) {
1659         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1660         assertTrue(lock.toString().contains("Write locks = 0"));
1661         assertTrue(lock.toString().contains("Read locks = 0"));
1662         lock.writeLock().lock();
1663         assertTrue(lock.toString().contains("Write locks = 1"));
1664         assertTrue(lock.toString().contains("Read locks = 0"));
1665         lock.writeLock().lock();
1666         assertTrue(lock.toString().contains("Write locks = 2"));
1667         assertTrue(lock.toString().contains("Read locks = 0"));
1668         lock.writeLock().unlock();
1669         lock.writeLock().unlock();
1670         lock.readLock().lock();
1671         assertTrue(lock.toString().contains("Write locks = 0"));
1672         assertTrue(lock.toString().contains("Read locks = 1"));
1673         lock.readLock().lock();
1674         assertTrue(lock.toString().contains("Write locks = 0"));
1675         assertTrue(lock.toString().contains("Read locks = 2"));
1676     }
1677 
1678     /**
1679      * readLock.toString indicates current lock state
1680      */
testReadLockToString()1681     public void testReadLockToString()      { testReadLockToString(false); }
testReadLockToString_fair()1682     public void testReadLockToString_fair() { testReadLockToString(true); }
testReadLockToString(boolean fair)1683     public void testReadLockToString(boolean fair) {
1684         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1685         assertTrue(lock.readLock().toString().contains("Read locks = 0"));
1686         lock.readLock().lock();
1687         assertTrue(lock.readLock().toString().contains("Read locks = 1"));
1688         lock.readLock().lock();
1689         assertTrue(lock.readLock().toString().contains("Read locks = 2"));
1690         lock.readLock().unlock();
1691         assertTrue(lock.readLock().toString().contains("Read locks = 1"));
1692         lock.readLock().unlock();
1693         assertTrue(lock.readLock().toString().contains("Read locks = 0"));
1694     }
1695 
1696     /**
1697      * writeLock.toString indicates current lock state
1698      */
testWriteLockToString()1699     public void testWriteLockToString()      { testWriteLockToString(false); }
testWriteLockToString_fair()1700     public void testWriteLockToString_fair() { testWriteLockToString(true); }
testWriteLockToString(boolean fair)1701     public void testWriteLockToString(boolean fair) {
1702         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1703         assertTrue(lock.writeLock().toString().contains("Unlocked"));
1704         lock.writeLock().lock();
1705         assertTrue(lock.writeLock().toString().contains("Locked by"));
1706         lock.writeLock().unlock();
1707         assertTrue(lock.writeLock().toString().contains("Unlocked"));
1708     }
1709 
1710 }
1711