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