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