ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ReentrantReadWriteLockTest.java
Revision: 1.48
Committed: Mon May 2 00:06:45 2011 UTC (13 years ago) by jsr166
Branch: MAIN
Changes since 1.47: +1 -2 lines
Log Message:
Improve testReadLockInterruptibly_Interrupted

File Contents

# Content
1 /*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain, as explained at
4 * http://creativecommons.org/publicdomain/zero/1.0/
5 * Other contributors include Andrew Wright, Jeffrey Hayes,
6 * Pat Fisher, Mike Judd.
7 */
8
9 import junit.framework.*;
10 import java.util.concurrent.locks.*;
11 import java.util.concurrent.*;
12 import static java.util.concurrent.TimeUnit.MILLISECONDS;
13 import java.io.*;
14 import java.util.*;
15
16 public class ReentrantReadWriteLockTest extends JSR166TestCase {
17 public static void main(String[] args) {
18 junit.textui.TestRunner.run(suite());
19 }
20 public static Test suite() {
21 return new TestSuite(ReentrantReadWriteLockTest.class);
22 }
23
24 /**
25 * A runnable calling lockInterruptibly
26 */
27 class InterruptibleLockRunnable extends CheckedRunnable {
28 final ReentrantReadWriteLock lock;
29 InterruptibleLockRunnable(ReentrantReadWriteLock l) { lock = l; }
30 public void realRun() throws InterruptedException {
31 lock.writeLock().lockInterruptibly();
32 }
33 }
34
35
36 /**
37 * A runnable calling lockInterruptibly that expects to be
38 * interrupted
39 */
40 class InterruptedLockRunnable extends CheckedInterruptedRunnable {
41 final ReentrantReadWriteLock lock;
42 InterruptedLockRunnable(ReentrantReadWriteLock l) { lock = l; }
43 public void realRun() throws InterruptedException {
44 lock.writeLock().lockInterruptibly();
45 }
46 }
47
48 /**
49 * Subclass to expose protected methods
50 */
51 static class PublicReentrantReadWriteLock extends ReentrantReadWriteLock {
52 PublicReentrantReadWriteLock() { super(); }
53 public Collection<Thread> getQueuedThreads() {
54 return super.getQueuedThreads();
55 }
56 public Collection<Thread> getWaitingThreads(Condition c) {
57 return super.getWaitingThreads(c);
58 }
59 }
60
61 /**
62 * Releases lock, checking that it had a hold count of 1.
63 */
64 void releaseLock(ReentrantReadWriteLock.WriteLock lock) {
65 assertTrue(lock.isHeldByCurrentThread());
66 lock.unlock();
67 assertFalse(lock.isHeldByCurrentThread());
68 }
69
70 /**
71 * Constructor sets given fairness, and is in unlocked state
72 */
73 public void testConstructor() {
74 ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
75 assertFalse(rl.isFair());
76 assertFalse(rl.isWriteLocked());
77 assertEquals(0, rl.getReadLockCount());
78 ReentrantReadWriteLock r2 = new ReentrantReadWriteLock(true);
79 assertTrue(r2.isFair());
80 assertFalse(r2.isWriteLocked());
81 assertEquals(0, r2.getReadLockCount());
82 ReentrantReadWriteLock r3 = new ReentrantReadWriteLock(false);
83 assertFalse(r3.isFair());
84 assertFalse(r3.isWriteLocked());
85 assertEquals(0, r3.getReadLockCount());
86 }
87
88 /**
89 * write-locking and read-locking an unlocked lock succeed
90 */
91 public void testLock() {
92 ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
93 rl.writeLock().lock();
94 assertTrue(rl.isWriteLocked());
95 assertTrue(rl.isWriteLockedByCurrentThread());
96 assertTrue(rl.writeLock().isHeldByCurrentThread());
97 assertEquals(0, rl.getReadLockCount());
98 rl.writeLock().unlock();
99 assertFalse(rl.isWriteLocked());
100 assertFalse(rl.isWriteLockedByCurrentThread());
101 assertFalse(rl.writeLock().isHeldByCurrentThread());
102 assertEquals(0, rl.getReadLockCount());
103 rl.readLock().lock();
104 assertFalse(rl.isWriteLocked());
105 assertFalse(rl.isWriteLockedByCurrentThread());
106 assertEquals(1, rl.getReadLockCount());
107 rl.readLock().unlock();
108 assertFalse(rl.isWriteLocked());
109 assertFalse(rl.isWriteLockedByCurrentThread());
110 assertEquals(0, rl.getReadLockCount());
111 }
112
113
114 /**
115 * locking an unlocked fair lock succeeds
116 */
117 public void testFairLock() {
118 ReentrantReadWriteLock rl = new ReentrantReadWriteLock(true);
119 rl.writeLock().lock();
120 assertTrue(rl.isWriteLocked());
121 assertTrue(rl.isWriteLockedByCurrentThread());
122 assertTrue(rl.writeLock().isHeldByCurrentThread());
123 assertEquals(0, rl.getReadLockCount());
124 rl.writeLock().unlock();
125 assertFalse(rl.isWriteLocked());
126 assertFalse(rl.isWriteLockedByCurrentThread());
127 assertFalse(rl.writeLock().isHeldByCurrentThread());
128 assertEquals(0, rl.getReadLockCount());
129 rl.readLock().lock();
130 assertFalse(rl.isWriteLocked());
131 assertFalse(rl.isWriteLockedByCurrentThread());
132 assertEquals(1, rl.getReadLockCount());
133 rl.readLock().unlock();
134 assertFalse(rl.isWriteLocked());
135 assertFalse(rl.isWriteLockedByCurrentThread());
136 assertEquals(0, rl.getReadLockCount());
137 }
138
139 /**
140 * getWriteHoldCount returns number of recursive holds
141 */
142 public void testGetWriteHoldCount() {
143 ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
144 for (int i = 1; i <= SIZE; i++) {
145 lock.writeLock().lock();
146 assertEquals(i,lock.getWriteHoldCount());
147 }
148 for (int i = SIZE; i > 0; i--) {
149 lock.writeLock().unlock();
150 assertEquals(i-1,lock.getWriteHoldCount());
151 }
152 }
153
154 /**
155 * WriteLock.getHoldCount returns number of recursive holds
156 */
157 public void testGetHoldCount() {
158 ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
159 for (int i = 1; i <= SIZE; i++) {
160 lock.writeLock().lock();
161 assertEquals(i,lock.writeLock().getHoldCount());
162 }
163 for (int i = SIZE; i > 0; i--) {
164 lock.writeLock().unlock();
165 assertEquals(i-1,lock.writeLock().getHoldCount());
166 }
167 }
168
169 /**
170 * getReadHoldCount returns number of recursive holds
171 */
172 public void testGetReadHoldCount() {
173 ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
174 for (int i = 1; i <= SIZE; i++) {
175 lock.readLock().lock();
176 assertEquals(i,lock.getReadHoldCount());
177 }
178 for (int i = SIZE; i > 0; i--) {
179 lock.readLock().unlock();
180 assertEquals(i-1,lock.getReadHoldCount());
181 }
182 }
183
184
185 /**
186 * write-unlocking an unlocked lock throws IllegalMonitorStateException
187 */
188 public void testUnlock_IllegalMonitorStateException() {
189 ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
190 try {
191 rl.writeLock().unlock();
192 shouldThrow();
193 } catch (IllegalMonitorStateException success) {}
194 }
195
196
197 /**
198 * write-lockInterruptibly is interruptible
199 */
200 public void testWriteLockInterruptibly_Interrupted() throws Exception {
201 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
202 lock.writeLock().lock();
203 Thread t = newStartedThread(new CheckedInterruptedRunnable() {
204 public void realRun() throws InterruptedException {
205 lock.writeLock().lockInterruptibly();
206 }});
207
208 Thread.sleep(SHORT_DELAY_MS);
209 t.interrupt();
210 t.join();
211 releaseLock(lock.writeLock());
212 }
213
214 /**
215 * timed write-tryLock is interruptible
216 */
217 public void testWriteTryLock_Interrupted() throws InterruptedException {
218 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
219 lock.writeLock().lock();
220 Thread t = newStartedThread(new CheckedInterruptedRunnable() {
221 public void realRun() throws InterruptedException {
222 lock.writeLock().tryLock(SMALL_DELAY_MS, MILLISECONDS);
223 }});
224
225 Thread.sleep(SHORT_DELAY_MS);
226 t.interrupt();
227 t.join();
228 releaseLock(lock.writeLock());
229 }
230
231 /**
232 * read-lockInterruptibly is interruptible
233 */
234 public void testReadLockInterruptibly_Interrupted() throws InterruptedException {
235 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
236 lock.writeLock().lock();
237 Thread t = newStartedThread(new CheckedInterruptedRunnable() {
238 public void realRun() throws InterruptedException {
239 lock.readLock().lockInterruptibly();
240 }});
241
242 Thread.sleep(SHORT_DELAY_MS);
243 t.interrupt();
244 t.join();
245 releaseLock(lock.writeLock());
246 }
247
248 /**
249 * timed read-tryLock is interruptible
250 */
251 public void testReadTryLock_Interrupted() throws InterruptedException {
252 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
253 lock.writeLock().lock();
254 Thread t = newStartedThread(new CheckedInterruptedRunnable() {
255 public void realRun() throws InterruptedException {
256 lock.readLock().tryLock(LONG_DELAY_MS, MILLISECONDS);
257 }});
258
259 Thread.sleep(SHORT_DELAY_MS);
260 t.interrupt();
261 t.join();
262 }
263
264
265 /**
266 * write-tryLock fails if locked
267 */
268 public void testWriteTryLockWhenLocked() throws InterruptedException {
269 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
270 lock.writeLock().lock();
271 Thread t = newStartedThread(new CheckedRunnable() {
272 public void realRun() {
273 assertFalse(lock.writeLock().tryLock());
274 }});
275
276 t.join();
277 lock.writeLock().unlock();
278 }
279
280 /**
281 * read-tryLock fails if locked
282 */
283 public void testReadTryLockWhenLocked() throws InterruptedException {
284 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
285 lock.writeLock().lock();
286 Thread t = newStartedThread(new CheckedRunnable() {
287 public void realRun() {
288 assertFalse(lock.readLock().tryLock());
289 }});
290
291 t.join();
292 lock.writeLock().unlock();
293 }
294
295 /**
296 * Multiple threads can hold a read lock when not write-locked
297 */
298 public void testMultipleReadLocks() throws InterruptedException {
299 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
300 lock.readLock().lock();
301 Thread t = newStartedThread(new CheckedRunnable() {
302 public void realRun() {
303 assertTrue(lock.readLock().tryLock());
304 lock.readLock().unlock();
305 }});
306
307 t.join();
308 lock.readLock().unlock();
309 }
310
311 /**
312 * A writelock succeeds after reading threads unlock
313 */
314 public void testWriteAfterMultipleReadLocks() throws InterruptedException {
315 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
316 lock.readLock().lock();
317 Thread t1 = newStartedThread(new CheckedRunnable() {
318 public void realRun() {
319 lock.readLock().lock();
320 lock.readLock().unlock();
321 }});
322 Thread t2 = newStartedThread(new CheckedRunnable() {
323 public void realRun() {
324 lock.writeLock().lock();
325 lock.writeLock().unlock();
326 }});
327
328 Thread.sleep(SHORT_DELAY_MS);
329 lock.readLock().unlock();
330 t1.join(MEDIUM_DELAY_MS);
331 t2.join(MEDIUM_DELAY_MS);
332 assertTrue(!t1.isAlive());
333 assertTrue(!t2.isAlive());
334 }
335
336 /**
337 * Readlocks succeed after a writing thread unlocks
338 */
339 public void testReadAfterWriteLock() throws InterruptedException {
340 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
341 lock.writeLock().lock();
342 Thread t1 = newStartedThread(new CheckedRunnable() {
343 public void realRun() {
344 lock.readLock().lock();
345 lock.readLock().unlock();
346 }});
347 Thread t2 = newStartedThread(new CheckedRunnable() {
348 public void realRun() {
349 lock.readLock().lock();
350 lock.readLock().unlock();
351 }});
352
353 Thread.sleep(SHORT_DELAY_MS);
354 lock.writeLock().unlock();
355 t1.join(MEDIUM_DELAY_MS);
356 t2.join(MEDIUM_DELAY_MS);
357 assertTrue(!t1.isAlive());
358 assertTrue(!t2.isAlive());
359 }
360
361 /**
362 * Read trylock succeeds if write locked by current thread
363 */
364 public void testReadHoldingWriteLock() {
365 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
366 lock.writeLock().lock();
367 assertTrue(lock.readLock().tryLock());
368 lock.readLock().unlock();
369 lock.writeLock().unlock();
370 }
371
372 /**
373 * Read lock succeeds if write locked by current thread even if
374 * other threads are waiting for readlock
375 */
376 public void testReadHoldingWriteLock2() throws InterruptedException {
377 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
378 lock.writeLock().lock();
379 Thread t1 = newStartedThread(new CheckedRunnable() {
380 public void realRun() {
381 lock.readLock().lock();
382 lock.readLock().unlock();
383 }});
384 Thread t2 = newStartedThread(new CheckedRunnable() {
385 public void realRun() {
386 lock.readLock().lock();
387 lock.readLock().unlock();
388 }});
389
390 lock.readLock().lock();
391 lock.readLock().unlock();
392 Thread.sleep(SHORT_DELAY_MS);
393 lock.readLock().lock();
394 lock.readLock().unlock();
395 lock.writeLock().unlock();
396 t1.join(MEDIUM_DELAY_MS);
397 t2.join(MEDIUM_DELAY_MS);
398 assertTrue(!t1.isAlive());
399 assertTrue(!t2.isAlive());
400 }
401
402 /**
403 * Read lock succeeds if write locked by current thread even if
404 * other threads are waiting for writelock
405 */
406 public void testReadHoldingWriteLock3() throws InterruptedException {
407 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
408 lock.writeLock().lock();
409 Thread t1 = newStartedThread(new CheckedRunnable() {
410 public void realRun() {
411 lock.writeLock().lock();
412 lock.writeLock().unlock();
413 }});
414 Thread t2 = newStartedThread(new CheckedRunnable() {
415 public void realRun() {
416 lock.writeLock().lock();
417 lock.writeLock().unlock();
418 }});
419
420 lock.readLock().lock();
421 lock.readLock().unlock();
422 Thread.sleep(SHORT_DELAY_MS);
423 lock.readLock().lock();
424 lock.readLock().unlock();
425 lock.writeLock().unlock();
426 t1.join(MEDIUM_DELAY_MS);
427 t2.join(MEDIUM_DELAY_MS);
428 assertTrue(!t1.isAlive());
429 assertTrue(!t2.isAlive());
430 }
431
432
433 /**
434 * Write lock succeeds if write locked by current thread even if
435 * other threads are waiting for writelock
436 */
437 public void testWriteHoldingWriteLock4() throws InterruptedException {
438 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
439 lock.writeLock().lock();
440 Thread t1 = newStartedThread(new CheckedRunnable() {
441 public void realRun() {
442 lock.writeLock().lock();
443 lock.writeLock().unlock();
444 }});
445 Thread t2 = newStartedThread(new CheckedRunnable() {
446 public void realRun() {
447 lock.writeLock().lock();
448 lock.writeLock().unlock();
449 }});
450
451 lock.writeLock().lock();
452 lock.writeLock().unlock();
453 Thread.sleep(SHORT_DELAY_MS);
454 lock.writeLock().lock();
455 lock.writeLock().unlock();
456 lock.writeLock().unlock();
457 t1.join(MEDIUM_DELAY_MS);
458 t2.join(MEDIUM_DELAY_MS);
459 assertTrue(!t1.isAlive());
460 assertTrue(!t2.isAlive());
461 }
462
463
464 /**
465 * Fair Read trylock succeeds if write locked by current thread
466 */
467 public void testReadHoldingWriteLockFair() {
468 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
469 lock.writeLock().lock();
470 assertTrue(lock.readLock().tryLock());
471 lock.readLock().unlock();
472 lock.writeLock().unlock();
473 }
474
475 /**
476 * Fair Read lock succeeds if write locked by current thread even if
477 * other threads are waiting for readlock
478 */
479 public void testReadHoldingWriteLockFair2() throws InterruptedException {
480 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
481 lock.writeLock().lock();
482 Thread t1 = newStartedThread(new CheckedRunnable() {
483 public void realRun() {
484 lock.readLock().lock();
485 lock.readLock().unlock();
486 }});
487 Thread t2 = newStartedThread(new CheckedRunnable() {
488 public void realRun() {
489 lock.readLock().lock();
490 lock.readLock().unlock();
491 }});
492
493 lock.readLock().lock();
494 lock.readLock().unlock();
495 Thread.sleep(SHORT_DELAY_MS);
496 lock.readLock().lock();
497 lock.readLock().unlock();
498 lock.writeLock().unlock();
499 t1.join(MEDIUM_DELAY_MS);
500 t2.join(MEDIUM_DELAY_MS);
501 assertTrue(!t1.isAlive());
502 assertTrue(!t2.isAlive());
503 }
504
505
506 /**
507 * Fair Read lock succeeds if write locked by current thread even if
508 * other threads are waiting for writelock
509 */
510 public void testReadHoldingWriteLockFair3() throws InterruptedException {
511 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
512 lock.writeLock().lock();
513 Thread t1 = newStartedThread(new CheckedRunnable() {
514 public void realRun() {
515 lock.writeLock().lock();
516 lock.writeLock().unlock();
517 }});
518 Thread t2 = newStartedThread(new CheckedRunnable() {
519 public void realRun() {
520 lock.writeLock().lock();
521 lock.writeLock().unlock();
522 }});
523
524 lock.readLock().lock();
525 lock.readLock().unlock();
526 Thread.sleep(SHORT_DELAY_MS);
527 lock.readLock().lock();
528 lock.readLock().unlock();
529 lock.writeLock().unlock();
530 t1.join(MEDIUM_DELAY_MS);
531 t2.join(MEDIUM_DELAY_MS);
532 assertTrue(!t1.isAlive());
533 assertTrue(!t2.isAlive());
534 }
535
536
537 /**
538 * Fair Write lock succeeds if write locked by current thread even if
539 * other threads are waiting for writelock
540 */
541 public void testWriteHoldingWriteLockFair4() throws InterruptedException {
542 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
543 lock.writeLock().lock();
544 Thread t1 = newStartedThread(new CheckedRunnable() {
545 public void realRun() {
546 lock.writeLock().lock();
547 lock.writeLock().unlock();
548 }});
549 Thread t2 = newStartedThread(new CheckedRunnable() {
550 public void realRun() {
551 lock.writeLock().lock();
552 lock.writeLock().unlock();
553 }});
554
555 Thread.sleep(SHORT_DELAY_MS);
556 assertTrue(lock.isWriteLockedByCurrentThread());
557 assertEquals(1, lock.getWriteHoldCount());
558 lock.writeLock().lock();
559 assertEquals(2, lock.getWriteHoldCount());
560 lock.writeLock().unlock();
561 lock.writeLock().lock();
562 lock.writeLock().unlock();
563 lock.writeLock().unlock();
564 t1.join(MEDIUM_DELAY_MS);
565 t2.join(MEDIUM_DELAY_MS);
566 assertTrue(!t1.isAlive());
567 assertTrue(!t2.isAlive());
568 }
569
570
571 /**
572 * Read tryLock succeeds if readlocked but not writelocked
573 */
574 public void testTryLockWhenReadLocked() throws InterruptedException {
575 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
576 lock.readLock().lock();
577 Thread t = newStartedThread(new CheckedRunnable() {
578 public void realRun() {
579 assertTrue(lock.readLock().tryLock());
580 lock.readLock().unlock();
581 }});
582
583 t.join();
584 lock.readLock().unlock();
585 }
586
587 /**
588 * write tryLock fails when readlocked
589 */
590 public void testWriteTryLockWhenReadLocked() throws InterruptedException {
591 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
592 lock.readLock().lock();
593 Thread t = newStartedThread(new CheckedRunnable() {
594 public void realRun() {
595 assertFalse(lock.writeLock().tryLock());
596 }});
597
598 t.join();
599 lock.readLock().unlock();
600 }
601
602
603 /**
604 * Fair Read tryLock succeeds if readlocked but not writelocked
605 */
606 public void testTryLockWhenReadLockedFair() throws InterruptedException {
607 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
608 lock.readLock().lock();
609 Thread t = newStartedThread(new CheckedRunnable() {
610 public void realRun() {
611 assertTrue(lock.readLock().tryLock());
612 lock.readLock().unlock();
613 }});
614
615 t.join();
616 lock.readLock().unlock();
617 }
618
619
620
621 /**
622 * Fair write tryLock fails when readlocked
623 */
624 public void testWriteTryLockWhenReadLockedFair() throws InterruptedException {
625 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
626 lock.readLock().lock();
627 Thread t = newStartedThread(new CheckedRunnable() {
628 public void realRun() {
629 assertFalse(lock.writeLock().tryLock());
630 }});
631
632 t.join();
633 lock.readLock().unlock();
634 }
635
636
637
638 /**
639 * write timed tryLock times out if locked
640 */
641 public void testWriteTryLock_Timeout() throws InterruptedException {
642 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
643 lock.writeLock().lock();
644 Thread t = newStartedThread(new CheckedRunnable() {
645 public void realRun() throws InterruptedException {
646 assertFalse(lock.writeLock().tryLock(1, MILLISECONDS));
647 }});
648
649 t.join();
650 assertTrue(lock.writeLock().isHeldByCurrentThread());
651 lock.writeLock().unlock();
652 }
653
654 /**
655 * read timed tryLock times out if write-locked
656 */
657 public void testReadTryLock_Timeout() throws InterruptedException {
658 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
659 lock.writeLock().lock();
660 Thread t = newStartedThread(new CheckedRunnable() {
661 public void realRun() throws InterruptedException {
662 assertFalse(lock.readLock().tryLock(1, MILLISECONDS));
663 }});
664
665 t.join();
666 assertTrue(lock.writeLock().isHeldByCurrentThread());
667 lock.writeLock().unlock();
668 }
669
670
671 /**
672 * write lockInterruptibly succeeds if lock free else is interruptible
673 */
674 public void testWriteLockInterruptibly() throws InterruptedException {
675 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
676 lock.writeLock().lockInterruptibly();
677 Thread t = newStartedThread(new CheckedInterruptedRunnable() {
678 public void realRun() throws InterruptedException {
679 lock.writeLock().lockInterruptibly();
680 }});
681
682 Thread.sleep(SHORT_DELAY_MS);
683 t.interrupt();
684 Thread.sleep(SHORT_DELAY_MS);
685 t.join();
686 lock.writeLock().unlock();
687 }
688
689 /**
690 * read lockInterruptibly succeeds if lock free else is interruptible
691 */
692 public void testReadLockInterruptibly() throws InterruptedException {
693 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
694 lock.writeLock().lockInterruptibly();
695 Thread t = newStartedThread(new CheckedInterruptedRunnable() {
696 public void realRun() throws InterruptedException {
697 lock.readLock().lockInterruptibly();
698 }});
699
700 Thread.sleep(SHORT_DELAY_MS);
701 t.interrupt();
702 t.join();
703 lock.writeLock().unlock();
704 }
705
706 /**
707 * Calling await without holding lock throws IllegalMonitorStateException
708 */
709 public void testAwait_IllegalMonitor() throws InterruptedException {
710 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
711 final Condition c = lock.writeLock().newCondition();
712 try {
713 c.await();
714 shouldThrow();
715 } catch (IllegalMonitorStateException success) {}
716 }
717
718 /**
719 * Calling signal without holding lock throws IllegalMonitorStateException
720 */
721 public void testSignal_IllegalMonitor() {
722 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
723 final Condition c = lock.writeLock().newCondition();
724 try {
725 c.signal();
726 shouldThrow();
727 } catch (IllegalMonitorStateException success) {}
728 }
729
730 /**
731 * awaitNanos without a signal times out
732 */
733 public void testAwaitNanos_Timeout() throws InterruptedException {
734 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
735 final Condition c = lock.writeLock().newCondition();
736
737 lock.writeLock().lock();
738 long t = c.awaitNanos(100);
739 assertTrue(t <= 0);
740 lock.writeLock().unlock();
741 }
742
743
744 /**
745 * timed await without a signal times out
746 */
747 public void testAwait_Timeout() throws InterruptedException {
748 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
749 final Condition c = lock.writeLock().newCondition();
750 lock.writeLock().lock();
751 assertFalse(c.await(SHORT_DELAY_MS, MILLISECONDS));
752 lock.writeLock().unlock();
753 }
754
755 /**
756 * awaitUntil without a signal times out
757 */
758 public void testAwaitUntil_Timeout() throws InterruptedException {
759 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
760 final Condition c = lock.writeLock().newCondition();
761 lock.writeLock().lock();
762 java.util.Date d = new java.util.Date();
763 assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
764 lock.writeLock().unlock();
765 }
766
767 /**
768 * await returns when signalled
769 */
770 public void testAwait() throws InterruptedException {
771 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
772 final Condition c = lock.writeLock().newCondition();
773 Thread t = newStartedThread(new CheckedRunnable() {
774 public void realRun() throws InterruptedException {
775 lock.writeLock().lock();
776 c.await();
777 lock.writeLock().unlock();
778 }});
779
780 Thread.sleep(SHORT_DELAY_MS);
781 lock.writeLock().lock();
782 c.signal();
783 lock.writeLock().unlock();
784 t.join(SHORT_DELAY_MS);
785 assertFalse(t.isAlive());
786 }
787
788 /** A helper class for uninterruptible wait tests */
789 class UninterruptableThread extends Thread {
790 private Lock lock;
791 private Condition c;
792
793 public volatile boolean canAwake = false;
794 public volatile boolean interrupted = false;
795 public volatile boolean lockStarted = false;
796
797 public UninterruptableThread(Lock lock, Condition c) {
798 this.lock = lock;
799 this.c = c;
800 }
801
802 public synchronized void run() {
803 lock.lock();
804 lockStarted = true;
805
806 while (!canAwake) {
807 c.awaitUninterruptibly();
808 }
809
810 interrupted = isInterrupted();
811 lock.unlock();
812 }
813 }
814
815 /**
816 * awaitUninterruptibly doesn't abort on interrupt
817 */
818 public void testAwaitUninterruptibly() throws InterruptedException {
819 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
820 final Condition c = lock.writeLock().newCondition();
821 UninterruptableThread thread = new UninterruptableThread(lock.writeLock(), c);
822
823 thread.start();
824
825 while (!thread.lockStarted) {
826 Thread.sleep(100);
827 }
828
829 lock.writeLock().lock();
830 try {
831 thread.interrupt();
832 thread.canAwake = true;
833 c.signal();
834 } finally {
835 lock.writeLock().unlock();
836 }
837
838 thread.join();
839 assertTrue(thread.interrupted);
840 assertFalse(thread.isAlive());
841 }
842
843 /**
844 * await is interruptible
845 */
846 public void testAwait_Interrupt() throws InterruptedException {
847 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
848 final Condition c = lock.writeLock().newCondition();
849 Thread t = newStartedThread(new CheckedInterruptedRunnable() {
850 public void realRun() throws InterruptedException {
851 lock.writeLock().lock();
852 c.await();
853 lock.writeLock().unlock();
854 }});
855
856 Thread.sleep(SHORT_DELAY_MS);
857 t.interrupt();
858 t.join(SHORT_DELAY_MS);
859 assertFalse(t.isAlive());
860 }
861
862 /**
863 * awaitNanos is interruptible
864 */
865 public void testAwaitNanos_Interrupt() throws InterruptedException {
866 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
867 final Condition c = lock.writeLock().newCondition();
868 Thread t = newStartedThread(new CheckedInterruptedRunnable() {
869 public void realRun() throws InterruptedException {
870 lock.writeLock().lock();
871 c.awaitNanos(MILLISECONDS.toNanos(LONG_DELAY_MS));
872 lock.writeLock().unlock();
873 }});
874
875 Thread.sleep(SHORT_DELAY_MS);
876 t.interrupt();
877 t.join(SHORT_DELAY_MS);
878 assertFalse(t.isAlive());
879 }
880
881 /**
882 * awaitUntil is interruptible
883 */
884 public void testAwaitUntil_Interrupt() throws InterruptedException {
885 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
886 final Condition c = lock.writeLock().newCondition();
887 Thread t = newStartedThread(new CheckedInterruptedRunnable() {
888 public void realRun() throws InterruptedException {
889 lock.writeLock().lock();
890 java.util.Date d = new java.util.Date();
891 c.awaitUntil(new java.util.Date(d.getTime() + 10000));
892 lock.writeLock().unlock();
893 }});
894
895 Thread.sleep(SHORT_DELAY_MS);
896 t.interrupt();
897 t.join(SHORT_DELAY_MS);
898 assertFalse(t.isAlive());
899 }
900
901 /**
902 * signalAll wakes up all threads
903 */
904 public void testSignalAll() throws InterruptedException {
905 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
906 final Condition c = lock.writeLock().newCondition();
907 Thread t1 = newStartedThread(new CheckedRunnable() {
908 public void realRun() throws InterruptedException {
909 lock.writeLock().lock();
910 c.await();
911 lock.writeLock().unlock();
912 }});
913
914 Thread t2 = newStartedThread(new CheckedRunnable() {
915 public void realRun() throws InterruptedException {
916 lock.writeLock().lock();
917 c.await();
918 lock.writeLock().unlock();
919 }});
920
921 Thread.sleep(SHORT_DELAY_MS);
922 lock.writeLock().lock();
923 c.signalAll();
924 lock.writeLock().unlock();
925 t1.join(SHORT_DELAY_MS);
926 t2.join(SHORT_DELAY_MS);
927 assertFalse(t1.isAlive());
928 assertFalse(t2.isAlive());
929 }
930
931 /**
932 * A serialized lock deserializes as unlocked
933 */
934 public void testSerialization() throws Exception {
935 ReentrantReadWriteLock l = new ReentrantReadWriteLock();
936 l.readLock().lock();
937 l.readLock().unlock();
938
939 ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
940 ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
941 out.writeObject(l);
942 out.close();
943
944 ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
945 ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
946 ReentrantReadWriteLock r = (ReentrantReadWriteLock) in.readObject();
947 r.readLock().lock();
948 r.readLock().unlock();
949 }
950
951 /**
952 * hasQueuedThreads reports whether there are waiting threads
953 */
954 public void testhasQueuedThreads() throws InterruptedException {
955 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
956 Thread t1 = new Thread(new InterruptedLockRunnable(lock));
957 Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
958 assertFalse(lock.hasQueuedThreads());
959 lock.writeLock().lock();
960 t1.start();
961 Thread.sleep(SHORT_DELAY_MS);
962 assertTrue(lock.hasQueuedThreads());
963 t2.start();
964 Thread.sleep(SHORT_DELAY_MS);
965 assertTrue(lock.hasQueuedThreads());
966 t1.interrupt();
967 Thread.sleep(SHORT_DELAY_MS);
968 assertTrue(lock.hasQueuedThreads());
969 lock.writeLock().unlock();
970 Thread.sleep(SHORT_DELAY_MS);
971 assertFalse(lock.hasQueuedThreads());
972 t1.join();
973 t2.join();
974 }
975
976 /**
977 * hasQueuedThread(null) throws NPE
978 */
979 public void testHasQueuedThreadNPE() {
980 final ReentrantReadWriteLock sync = new ReentrantReadWriteLock();
981 try {
982 sync.hasQueuedThread(null);
983 shouldThrow();
984 } catch (NullPointerException success) {}
985 }
986
987 /**
988 * hasQueuedThread reports whether a thread is queued.
989 */
990 public void testHasQueuedThread() throws InterruptedException {
991 final ReentrantReadWriteLock sync = new ReentrantReadWriteLock();
992 Thread t1 = new Thread(new InterruptedLockRunnable(sync));
993 Thread t2 = new Thread(new InterruptibleLockRunnable(sync));
994 assertFalse(sync.hasQueuedThread(t1));
995 assertFalse(sync.hasQueuedThread(t2));
996 sync.writeLock().lock();
997 t1.start();
998 Thread.sleep(SHORT_DELAY_MS);
999 assertTrue(sync.hasQueuedThread(t1));
1000 t2.start();
1001 Thread.sleep(SHORT_DELAY_MS);
1002 assertTrue(sync.hasQueuedThread(t1));
1003 assertTrue(sync.hasQueuedThread(t2));
1004 t1.interrupt();
1005 Thread.sleep(SHORT_DELAY_MS);
1006 assertFalse(sync.hasQueuedThread(t1));
1007 assertTrue(sync.hasQueuedThread(t2));
1008 sync.writeLock().unlock();
1009 Thread.sleep(SHORT_DELAY_MS);
1010 assertFalse(sync.hasQueuedThread(t1));
1011 Thread.sleep(SHORT_DELAY_MS);
1012 assertFalse(sync.hasQueuedThread(t2));
1013 t1.join();
1014 t2.join();
1015 }
1016
1017
1018 /**
1019 * getQueueLength reports number of waiting threads
1020 */
1021 public void testGetQueueLength() throws InterruptedException {
1022 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1023 Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1024 Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1025 assertEquals(0, lock.getQueueLength());
1026 lock.writeLock().lock();
1027 t1.start();
1028 Thread.sleep(SHORT_DELAY_MS);
1029 assertEquals(1, lock.getQueueLength());
1030 t2.start();
1031 Thread.sleep(SHORT_DELAY_MS);
1032 assertEquals(2, lock.getQueueLength());
1033 t1.interrupt();
1034 Thread.sleep(SHORT_DELAY_MS);
1035 assertEquals(1, lock.getQueueLength());
1036 lock.writeLock().unlock();
1037 Thread.sleep(SHORT_DELAY_MS);
1038 assertEquals(0, lock.getQueueLength());
1039 t1.join();
1040 t2.join();
1041 }
1042
1043 /**
1044 * getQueuedThreads includes waiting threads
1045 */
1046 public void testGetQueuedThreads() throws InterruptedException {
1047 final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
1048 Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1049 Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1050 assertTrue(lock.getQueuedThreads().isEmpty());
1051 lock.writeLock().lock();
1052 assertTrue(lock.getQueuedThreads().isEmpty());
1053 t1.start();
1054 Thread.sleep(SHORT_DELAY_MS);
1055 assertTrue(lock.getQueuedThreads().contains(t1));
1056 t2.start();
1057 Thread.sleep(SHORT_DELAY_MS);
1058 assertTrue(lock.getQueuedThreads().contains(t1));
1059 assertTrue(lock.getQueuedThreads().contains(t2));
1060 t1.interrupt();
1061 Thread.sleep(SHORT_DELAY_MS);
1062 assertFalse(lock.getQueuedThreads().contains(t1));
1063 assertTrue(lock.getQueuedThreads().contains(t2));
1064 lock.writeLock().unlock();
1065 Thread.sleep(SHORT_DELAY_MS);
1066 assertTrue(lock.getQueuedThreads().isEmpty());
1067 t1.join();
1068 t2.join();
1069 }
1070
1071 /**
1072 * hasWaiters throws NPE if null
1073 */
1074 public void testHasWaitersNPE() {
1075 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1076 try {
1077 lock.hasWaiters(null);
1078 shouldThrow();
1079 } catch (NullPointerException success) {}
1080 }
1081
1082 /**
1083 * getWaitQueueLength throws NPE if null
1084 */
1085 public void testGetWaitQueueLengthNPE() {
1086 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1087 try {
1088 lock.getWaitQueueLength(null);
1089 shouldThrow();
1090 } catch (NullPointerException success) {}
1091 }
1092
1093
1094 /**
1095 * getWaitingThreads throws NPE if null
1096 */
1097 public void testGetWaitingThreadsNPE() {
1098 final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
1099 try {
1100 lock.getWaitingThreads(null);
1101 shouldThrow();
1102 } catch (NullPointerException success) {}
1103 }
1104
1105 /**
1106 * hasWaiters throws IAE if not owned
1107 */
1108 public void testHasWaitersIAE() {
1109 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1110 final Condition c = lock.writeLock().newCondition();
1111 final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock();
1112 try {
1113 lock2.hasWaiters(c);
1114 shouldThrow();
1115 } catch (IllegalArgumentException success) {}
1116 }
1117
1118 /**
1119 * hasWaiters throws IMSE if not locked
1120 */
1121 public void testHasWaitersIMSE() {
1122 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1123 final Condition c = lock.writeLock().newCondition();
1124 try {
1125 lock.hasWaiters(c);
1126 shouldThrow();
1127 } catch (IllegalMonitorStateException success) {}
1128 }
1129
1130
1131 /**
1132 * getWaitQueueLength throws IAE if not owned
1133 */
1134 public void testGetWaitQueueLengthIAE() {
1135 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1136 final Condition c = lock.writeLock().newCondition();
1137 final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock();
1138 try {
1139 lock2.getWaitQueueLength(c);
1140 shouldThrow();
1141 } catch (IllegalArgumentException success) {}
1142 }
1143
1144 /**
1145 * getWaitQueueLength throws IMSE if not locked
1146 */
1147 public void testGetWaitQueueLengthIMSE() {
1148 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1149 final Condition c = lock.writeLock().newCondition();
1150 try {
1151 lock.getWaitQueueLength(c);
1152 shouldThrow();
1153 } catch (IllegalMonitorStateException success) {}
1154 }
1155
1156
1157 /**
1158 * getWaitingThreads throws IAE if not owned
1159 */
1160 public void testGetWaitingThreadsIAE() {
1161 final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
1162 final Condition c = lock.writeLock().newCondition();
1163 final PublicReentrantReadWriteLock lock2 = new PublicReentrantReadWriteLock();
1164 try {
1165 lock2.getWaitingThreads(c);
1166 shouldThrow();
1167 } catch (IllegalArgumentException success) {}
1168 }
1169
1170 /**
1171 * getWaitingThreads throws IMSE if not locked
1172 */
1173 public void testGetWaitingThreadsIMSE() {
1174 final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
1175 final Condition c = lock.writeLock().newCondition();
1176 try {
1177 lock.getWaitingThreads(c);
1178 shouldThrow();
1179 } catch (IllegalMonitorStateException success) {}
1180 }
1181
1182
1183 /**
1184 * hasWaiters returns true when a thread is waiting, else false
1185 */
1186 public void testHasWaiters() throws InterruptedException {
1187 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1188 final Condition c = lock.writeLock().newCondition();
1189 Thread t = newStartedThread(new CheckedRunnable() {
1190 public void realRun() throws InterruptedException {
1191 lock.writeLock().lock();
1192 assertFalse(lock.hasWaiters(c));
1193 assertEquals(0, lock.getWaitQueueLength(c));
1194 c.await();
1195 lock.writeLock().unlock();
1196 }});
1197
1198 Thread.sleep(SHORT_DELAY_MS);
1199 lock.writeLock().lock();
1200 assertTrue(lock.hasWaiters(c));
1201 assertEquals(1, lock.getWaitQueueLength(c));
1202 c.signal();
1203 lock.writeLock().unlock();
1204 Thread.sleep(SHORT_DELAY_MS);
1205 lock.writeLock().lock();
1206 assertFalse(lock.hasWaiters(c));
1207 assertEquals(0, lock.getWaitQueueLength(c));
1208 lock.writeLock().unlock();
1209 t.join(SHORT_DELAY_MS);
1210 assertFalse(t.isAlive());
1211 }
1212
1213 /**
1214 * getWaitQueueLength returns number of waiting threads
1215 */
1216 public void testGetWaitQueueLength() throws InterruptedException {
1217 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1218 final Condition c = lock.writeLock().newCondition();
1219 Thread t = newStartedThread(new CheckedRunnable() {
1220 public void realRun() throws InterruptedException {
1221 lock.writeLock().lock();
1222 assertFalse(lock.hasWaiters(c));
1223 assertEquals(0, lock.getWaitQueueLength(c));
1224 c.await();
1225 lock.writeLock().unlock();
1226 }});
1227
1228 Thread.sleep(SHORT_DELAY_MS);
1229 lock.writeLock().lock();
1230 assertTrue(lock.hasWaiters(c));
1231 assertEquals(1, lock.getWaitQueueLength(c));
1232 c.signal();
1233 lock.writeLock().unlock();
1234 Thread.sleep(SHORT_DELAY_MS);
1235 lock.writeLock().lock();
1236 assertFalse(lock.hasWaiters(c));
1237 assertEquals(0, lock.getWaitQueueLength(c));
1238 lock.writeLock().unlock();
1239 t.join(SHORT_DELAY_MS);
1240 assertFalse(t.isAlive());
1241 }
1242
1243
1244 /**
1245 * getWaitingThreads returns only and all waiting threads
1246 */
1247 public void testGetWaitingThreads() throws InterruptedException {
1248 final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
1249 final Condition c = lock.writeLock().newCondition();
1250 Thread t1 = new Thread(new CheckedRunnable() {
1251 public void realRun() throws InterruptedException {
1252 lock.writeLock().lock();
1253 assertTrue(lock.getWaitingThreads(c).isEmpty());
1254 c.await();
1255 lock.writeLock().unlock();
1256 }});
1257
1258 Thread t2 = new Thread(new CheckedRunnable() {
1259 public void realRun() throws InterruptedException {
1260 lock.writeLock().lock();
1261 assertFalse(lock.getWaitingThreads(c).isEmpty());
1262 c.await();
1263 lock.writeLock().unlock();
1264 }});
1265
1266 lock.writeLock().lock();
1267 assertTrue(lock.getWaitingThreads(c).isEmpty());
1268 lock.writeLock().unlock();
1269 t1.start();
1270 Thread.sleep(SHORT_DELAY_MS);
1271 t2.start();
1272 Thread.sleep(SHORT_DELAY_MS);
1273 lock.writeLock().lock();
1274 assertTrue(lock.hasWaiters(c));
1275 assertTrue(lock.getWaitingThreads(c).contains(t1));
1276 assertTrue(lock.getWaitingThreads(c).contains(t2));
1277 c.signalAll();
1278 lock.writeLock().unlock();
1279 Thread.sleep(SHORT_DELAY_MS);
1280 lock.writeLock().lock();
1281 assertFalse(lock.hasWaiters(c));
1282 assertTrue(lock.getWaitingThreads(c).isEmpty());
1283 lock.writeLock().unlock();
1284 t1.join(SHORT_DELAY_MS);
1285 t2.join(SHORT_DELAY_MS);
1286 assertFalse(t1.isAlive());
1287 assertFalse(t2.isAlive());
1288 }
1289
1290 /**
1291 * toString indicates current lock state
1292 */
1293 public void testToString() {
1294 ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1295 String us = lock.toString();
1296 assertTrue(us.indexOf("Write locks = 0") >= 0);
1297 assertTrue(us.indexOf("Read locks = 0") >= 0);
1298 lock.writeLock().lock();
1299 String ws = lock.toString();
1300 assertTrue(ws.indexOf("Write locks = 1") >= 0);
1301 assertTrue(ws.indexOf("Read locks = 0") >= 0);
1302 lock.writeLock().unlock();
1303 lock.readLock().lock();
1304 lock.readLock().lock();
1305 String rs = lock.toString();
1306 assertTrue(rs.indexOf("Write locks = 0") >= 0);
1307 assertTrue(rs.indexOf("Read locks = 2") >= 0);
1308 }
1309
1310 /**
1311 * readLock.toString indicates current lock state
1312 */
1313 public void testReadLockToString() {
1314 ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1315 String us = lock.readLock().toString();
1316 assertTrue(us.indexOf("Read locks = 0") >= 0);
1317 lock.readLock().lock();
1318 lock.readLock().lock();
1319 String rs = lock.readLock().toString();
1320 assertTrue(rs.indexOf("Read locks = 2") >= 0);
1321 }
1322
1323 /**
1324 * writeLock.toString indicates current lock state
1325 */
1326 public void testWriteLockToString() {
1327 ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1328 String us = lock.writeLock().toString();
1329 assertTrue(us.indexOf("Unlocked") >= 0);
1330 lock.writeLock().lock();
1331 String ls = lock.writeLock().toString();
1332 assertTrue(ls.indexOf("Locked") >= 0);
1333 }
1334
1335 }