ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ReentrantReadWriteLockTest.java
Revision: 1.84
Committed: Thu Sep 26 20:48:53 2019 UTC (4 years, 7 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.83: +8 -8 lines
Log Message:
whitespace

File Contents

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