ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ReentrantReadWriteLockTest.java
Revision: 1.76
Committed: Fri Jul 3 00:25:35 2015 UTC (8 years, 10 months ago) by jsr166
Branch: MAIN
Changes since 1.75: +1 -1 lines
Log Message:
minor improvements

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