ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ReentrantReadWriteLockTest.java
Revision: 1.33
Committed: Tue Nov 17 14:33:55 2009 UTC (14 years, 6 months ago) by jsr166
Branch: MAIN
Changes since 1.32: +105 -201 lines
Log Message:
use CheckedRunnable

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