ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ReentrantReadWriteLockTest.java
Revision: 1.20
Committed: Fri Jul 2 10:24:00 2004 UTC (19 years, 10 months ago) by dl
Branch: MAIN
Changes since 1.19: +100 -0 lines
Log Message:
Added tests for reentrant read acquire while hold write lock under contention

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