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