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