ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ReentrantReadWriteLockTest.java
Revision: 1.21
Committed: Thu Jan 20 00:39:13 2005 UTC (19 years, 4 months ago) by dl
Branch: MAIN
Changes since 1.20: +0 -2 lines
Log Message:
Weaken lock await assertion, add queue testRemoveElementAndAdd

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 lock.writeLock().unlock();
695 }
696 catch (Exception ex) {
697 unexpectedException();
698 }
699 }
700
701 /**
702 * awaitUntil without a signal times out
703 */
704 public void testAwaitUntil_Timeout() {
705 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
706 final Condition c = lock.writeLock().newCondition();
707 try {
708 lock.writeLock().lock();
709 java.util.Date d = new java.util.Date();
710 lock.writeLock().unlock();
711 }
712 catch (Exception ex) {
713 unexpectedException();
714 }
715 }
716
717 /**
718 * await returns when signalled
719 */
720 public void testAwait() {
721 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
722 final Condition c = lock.writeLock().newCondition();
723 Thread t = new Thread(new Runnable() {
724 public void run() {
725 try {
726 lock.writeLock().lock();
727 c.await();
728 lock.writeLock().unlock();
729 }
730 catch(InterruptedException e) {
731 threadUnexpectedException();
732 }
733 }
734 });
735
736 try {
737 t.start();
738 Thread.sleep(SHORT_DELAY_MS);
739 lock.writeLock().lock();
740 c.signal();
741 lock.writeLock().unlock();
742 t.join(SHORT_DELAY_MS);
743 assertFalse(t.isAlive());
744 }
745 catch (Exception ex) {
746 unexpectedException();
747 }
748 }
749
750 /**
751 * awaitUninterruptibly doesn't abort on interrupt
752 */
753 public void testAwaitUninterruptibly() {
754 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
755 final Condition c = lock.writeLock().newCondition();
756 Thread t = new Thread(new Runnable() {
757 public void run() {
758 lock.writeLock().lock();
759 c.awaitUninterruptibly();
760 lock.writeLock().unlock();
761 }
762 });
763
764 try {
765 t.start();
766 Thread.sleep(SHORT_DELAY_MS);
767 t.interrupt();
768 lock.writeLock().lock();
769 c.signal();
770 lock.writeLock().unlock();
771 assert(t.isInterrupted());
772 t.join(SHORT_DELAY_MS);
773 assertFalse(t.isAlive());
774 }
775 catch (Exception ex) {
776 unexpectedException();
777 }
778 }
779
780 /**
781 * await is interruptible
782 */
783 public void testAwait_Interrupt() {
784 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
785 final Condition c = lock.writeLock().newCondition();
786 Thread t = new Thread(new Runnable() {
787 public void run() {
788 try {
789 lock.writeLock().lock();
790 c.await();
791 lock.writeLock().unlock();
792 threadShouldThrow();
793 }
794 catch(InterruptedException success) {
795 }
796 }
797 });
798
799 try {
800 t.start();
801 Thread.sleep(SHORT_DELAY_MS);
802 t.interrupt();
803 t.join(SHORT_DELAY_MS);
804 assertFalse(t.isAlive());
805 }
806 catch (Exception ex) {
807 unexpectedException();
808 }
809 }
810
811 /**
812 * awaitNanos is interruptible
813 */
814 public void testAwaitNanos_Interrupt() {
815 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
816 final Condition c = lock.writeLock().newCondition();
817 Thread t = new Thread(new Runnable() {
818 public void run() {
819 try {
820 lock.writeLock().lock();
821 c.awaitNanos(SHORT_DELAY_MS * 2 * 1000000);
822 lock.writeLock().unlock();
823 threadShouldThrow();
824 }
825 catch(InterruptedException success) {
826 }
827 }
828 });
829
830 try {
831 t.start();
832 Thread.sleep(SHORT_DELAY_MS);
833 t.interrupt();
834 t.join(SHORT_DELAY_MS);
835 assertFalse(t.isAlive());
836 }
837 catch (Exception ex) {
838 unexpectedException();
839 }
840 }
841
842 /**
843 * awaitUntil is interruptible
844 */
845 public void testAwaitUntil_Interrupt() {
846 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
847 final Condition c = lock.writeLock().newCondition();
848 Thread t = new Thread(new Runnable() {
849 public void run() {
850 try {
851 lock.writeLock().lock();
852 java.util.Date d = new java.util.Date();
853 c.awaitUntil(new java.util.Date(d.getTime() + 10000));
854 lock.writeLock().unlock();
855 threadShouldThrow();
856 }
857 catch(InterruptedException success) {
858 }
859 }
860 });
861
862 try {
863 t.start();
864 Thread.sleep(SHORT_DELAY_MS);
865 t.interrupt();
866 t.join(SHORT_DELAY_MS);
867 assertFalse(t.isAlive());
868 }
869 catch (Exception ex) {
870 unexpectedException();
871 }
872 }
873
874 /**
875 * signalAll wakes up all threads
876 */
877 public void testSignalAll() {
878 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
879 final Condition c = lock.writeLock().newCondition();
880 Thread t1 = new Thread(new Runnable() {
881 public void run() {
882 try {
883 lock.writeLock().lock();
884 c.await();
885 lock.writeLock().unlock();
886 }
887 catch(InterruptedException e) {
888 threadUnexpectedException();
889 }
890 }
891 });
892
893 Thread t2 = new Thread(new Runnable() {
894 public void run() {
895 try {
896 lock.writeLock().lock();
897 c.await();
898 lock.writeLock().unlock();
899 }
900 catch(InterruptedException e) {
901 threadUnexpectedException();
902 }
903 }
904 });
905
906 try {
907 t1.start();
908 t2.start();
909 Thread.sleep(SHORT_DELAY_MS);
910 lock.writeLock().lock();
911 c.signalAll();
912 lock.writeLock().unlock();
913 t1.join(SHORT_DELAY_MS);
914 t2.join(SHORT_DELAY_MS);
915 assertFalse(t1.isAlive());
916 assertFalse(t2.isAlive());
917 }
918 catch (Exception ex) {
919 unexpectedException();
920 }
921 }
922
923 /**
924 * A serialized lock deserializes as unlocked
925 */
926 public void testSerialization() {
927 ReentrantReadWriteLock l = new ReentrantReadWriteLock();
928 l.readLock().lock();
929 l.readLock().unlock();
930
931 try {
932 ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
933 ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
934 out.writeObject(l);
935 out.close();
936
937 ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
938 ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
939 ReentrantReadWriteLock r = (ReentrantReadWriteLock) in.readObject();
940 r.readLock().lock();
941 r.readLock().unlock();
942 } catch(Exception e){
943 e.printStackTrace();
944 unexpectedException();
945 }
946 }
947
948 /**
949 * hasQueuedThreads reports whether there are waiting threads
950 */
951 public void testhasQueuedThreads() {
952 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
953 Thread t1 = new Thread(new InterruptedLockRunnable(lock));
954 Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
955 try {
956 assertFalse(lock.hasQueuedThreads());
957 lock.writeLock().lock();
958 t1.start();
959 Thread.sleep(SHORT_DELAY_MS);
960 assertTrue(lock.hasQueuedThreads());
961 t2.start();
962 Thread.sleep(SHORT_DELAY_MS);
963 assertTrue(lock.hasQueuedThreads());
964 t1.interrupt();
965 Thread.sleep(SHORT_DELAY_MS);
966 assertTrue(lock.hasQueuedThreads());
967 lock.writeLock().unlock();
968 Thread.sleep(SHORT_DELAY_MS);
969 assertFalse(lock.hasQueuedThreads());
970 t1.join();
971 t2.join();
972 } catch(Exception e){
973 unexpectedException();
974 }
975 }
976
977 /**
978 * hasQueuedThread(null) throws NPE
979 */
980 public void testHasQueuedThreadNPE() {
981 final ReentrantReadWriteLock sync = new ReentrantReadWriteLock();
982 try {
983 sync.hasQueuedThread(null);
984 shouldThrow();
985 } catch (NullPointerException success) {
986 }
987 }
988
989 /**
990 * hasQueuedThread reports whether a thread is queued.
991 */
992 public void testHasQueuedThread() {
993 final ReentrantReadWriteLock sync = new ReentrantReadWriteLock();
994 Thread t1 = new Thread(new InterruptedLockRunnable(sync));
995 Thread t2 = new Thread(new InterruptibleLockRunnable(sync));
996 try {
997 assertFalse(sync.hasQueuedThread(t1));
998 assertFalse(sync.hasQueuedThread(t2));
999 sync.writeLock().lock();
1000 t1.start();
1001 Thread.sleep(SHORT_DELAY_MS);
1002 assertTrue(sync.hasQueuedThread(t1));
1003 t2.start();
1004 Thread.sleep(SHORT_DELAY_MS);
1005 assertTrue(sync.hasQueuedThread(t1));
1006 assertTrue(sync.hasQueuedThread(t2));
1007 t1.interrupt();
1008 Thread.sleep(SHORT_DELAY_MS);
1009 assertFalse(sync.hasQueuedThread(t1));
1010 assertTrue(sync.hasQueuedThread(t2));
1011 sync.writeLock().unlock();
1012 Thread.sleep(SHORT_DELAY_MS);
1013 assertFalse(sync.hasQueuedThread(t1));
1014 Thread.sleep(SHORT_DELAY_MS);
1015 assertFalse(sync.hasQueuedThread(t2));
1016 t1.join();
1017 t2.join();
1018 } catch(Exception e){
1019 unexpectedException();
1020 }
1021 }
1022
1023
1024 /**
1025 * getQueueLength reports number of waiting threads
1026 */
1027 public void testGetQueueLength() {
1028 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1029 Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1030 Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1031 try {
1032 assertEquals(0, lock.getQueueLength());
1033 lock.writeLock().lock();
1034 t1.start();
1035 Thread.sleep(SHORT_DELAY_MS);
1036 assertEquals(1, lock.getQueueLength());
1037 t2.start();
1038 Thread.sleep(SHORT_DELAY_MS);
1039 assertEquals(2, lock.getQueueLength());
1040 t1.interrupt();
1041 Thread.sleep(SHORT_DELAY_MS);
1042 assertEquals(1, lock.getQueueLength());
1043 lock.writeLock().unlock();
1044 Thread.sleep(SHORT_DELAY_MS);
1045 assertEquals(0, lock.getQueueLength());
1046 t1.join();
1047 t2.join();
1048 } catch(Exception e){
1049 unexpectedException();
1050 }
1051 }
1052
1053 /**
1054 * getQueuedThreads includes waiting threads
1055 */
1056 public void testGetQueuedThreads() {
1057 final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
1058 Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1059 Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1060 try {
1061 assertTrue(lock.getQueuedThreads().isEmpty());
1062 lock.writeLock().lock();
1063 assertTrue(lock.getQueuedThreads().isEmpty());
1064 t1.start();
1065 Thread.sleep(SHORT_DELAY_MS);
1066 assertTrue(lock.getQueuedThreads().contains(t1));
1067 t2.start();
1068 Thread.sleep(SHORT_DELAY_MS);
1069 assertTrue(lock.getQueuedThreads().contains(t1));
1070 assertTrue(lock.getQueuedThreads().contains(t2));
1071 t1.interrupt();
1072 Thread.sleep(SHORT_DELAY_MS);
1073 assertFalse(lock.getQueuedThreads().contains(t1));
1074 assertTrue(lock.getQueuedThreads().contains(t2));
1075 lock.writeLock().unlock();
1076 Thread.sleep(SHORT_DELAY_MS);
1077 assertTrue(lock.getQueuedThreads().isEmpty());
1078 t1.join();
1079 t2.join();
1080 } catch(Exception e){
1081 unexpectedException();
1082 }
1083 }
1084
1085 /**
1086 * hasWaiters throws NPE if null
1087 */
1088 public void testHasWaitersNPE() {
1089 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1090 try {
1091 lock.hasWaiters(null);
1092 shouldThrow();
1093 } catch (NullPointerException success) {
1094 } catch (Exception ex) {
1095 unexpectedException();
1096 }
1097 }
1098
1099 /**
1100 * getWaitQueueLength throws NPE if null
1101 */
1102 public void testGetWaitQueueLengthNPE() {
1103 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1104 try {
1105 lock.getWaitQueueLength(null);
1106 shouldThrow();
1107 } catch (NullPointerException success) {
1108 } catch (Exception ex) {
1109 unexpectedException();
1110 }
1111 }
1112
1113
1114 /**
1115 * getWaitingThreads throws NPE if null
1116 */
1117 public void testGetWaitingThreadsNPE() {
1118 final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
1119 try {
1120 lock.getWaitingThreads(null);
1121 shouldThrow();
1122 } catch (NullPointerException success) {
1123 } catch (Exception ex) {
1124 unexpectedException();
1125 }
1126 }
1127
1128 /**
1129 * hasWaiters throws IAE if not owned
1130 */
1131 public void testHasWaitersIAE() {
1132 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1133 final Condition c = (lock.writeLock().newCondition());
1134 final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock();
1135 try {
1136 lock2.hasWaiters(c);
1137 shouldThrow();
1138 } catch (IllegalArgumentException success) {
1139 } catch (Exception ex) {
1140 unexpectedException();
1141 }
1142 }
1143
1144 /**
1145 * hasWaiters throws IMSE if not locked
1146 */
1147 public void testHasWaitersIMSE() {
1148 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1149 final Condition c = (lock.writeLock().newCondition());
1150 try {
1151 lock.hasWaiters(c);
1152 shouldThrow();
1153 } catch (IllegalMonitorStateException success) {
1154 } catch (Exception ex) {
1155 unexpectedException();
1156 }
1157 }
1158
1159
1160 /**
1161 * getWaitQueueLength throws IAE if not owned
1162 */
1163 public void testGetWaitQueueLengthIAE() {
1164 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1165 final Condition c = (lock.writeLock().newCondition());
1166 final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock();
1167 try {
1168 lock2.getWaitQueueLength(c);
1169 shouldThrow();
1170 } catch (IllegalArgumentException success) {
1171 } catch (Exception ex) {
1172 unexpectedException();
1173 }
1174 }
1175
1176 /**
1177 * getWaitQueueLength throws IMSE if not locked
1178 */
1179 public void testGetWaitQueueLengthIMSE() {
1180 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1181 final Condition c = (lock.writeLock().newCondition());
1182 try {
1183 lock.getWaitQueueLength(c);
1184 shouldThrow();
1185 } catch (IllegalMonitorStateException success) {
1186 } catch (Exception ex) {
1187 unexpectedException();
1188 }
1189 }
1190
1191
1192 /**
1193 * getWaitingThreads throws IAE if not owned
1194 */
1195 public void testGetWaitingThreadsIAE() {
1196 final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
1197 final Condition c = (lock.writeLock().newCondition());
1198 final PublicReentrantReadWriteLock lock2 = new PublicReentrantReadWriteLock();
1199 try {
1200 lock2.getWaitingThreads(c);
1201 shouldThrow();
1202 } catch (IllegalArgumentException success) {
1203 } catch (Exception ex) {
1204 unexpectedException();
1205 }
1206 }
1207
1208 /**
1209 * getWaitingThreads throws IMSE if not locked
1210 */
1211 public void testGetWaitingThreadsIMSE() {
1212 final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
1213 final Condition c = (lock.writeLock().newCondition());
1214 try {
1215 lock.getWaitingThreads(c);
1216 shouldThrow();
1217 } catch (IllegalMonitorStateException success) {
1218 } catch (Exception ex) {
1219 unexpectedException();
1220 }
1221 }
1222
1223
1224 /**
1225 * hasWaiters returns true when a thread is waiting, else false
1226 */
1227 public void testHasWaiters() {
1228 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1229 final Condition c = (lock.writeLock().newCondition());
1230 Thread t = new Thread(new Runnable() {
1231 public void run() {
1232 try {
1233 lock.writeLock().lock();
1234 threadAssertFalse(lock.hasWaiters(c));
1235 threadAssertEquals(0, lock.getWaitQueueLength(c));
1236 c.await();
1237 lock.writeLock().unlock();
1238 }
1239 catch(InterruptedException e) {
1240 threadUnexpectedException();
1241 }
1242 }
1243 });
1244
1245 try {
1246 t.start();
1247 Thread.sleep(SHORT_DELAY_MS);
1248 lock.writeLock().lock();
1249 assertTrue(lock.hasWaiters(c));
1250 assertEquals(1, lock.getWaitQueueLength(c));
1251 c.signal();
1252 lock.writeLock().unlock();
1253 Thread.sleep(SHORT_DELAY_MS);
1254 lock.writeLock().lock();
1255 assertFalse(lock.hasWaiters(c));
1256 assertEquals(0, lock.getWaitQueueLength(c));
1257 lock.writeLock().unlock();
1258 t.join(SHORT_DELAY_MS);
1259 assertFalse(t.isAlive());
1260 }
1261 catch (Exception ex) {
1262 unexpectedException();
1263 }
1264 }
1265
1266 /**
1267 * getWaitQueueLength returns number of waiting threads
1268 */
1269 public void testGetWaitQueueLength() {
1270 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1271 final Condition c = (lock.writeLock().newCondition());
1272 Thread t = new Thread(new Runnable() {
1273 public void run() {
1274 try {
1275 lock.writeLock().lock();
1276 threadAssertFalse(lock.hasWaiters(c));
1277 threadAssertEquals(0, lock.getWaitQueueLength(c));
1278 c.await();
1279 lock.writeLock().unlock();
1280 }
1281 catch(InterruptedException e) {
1282 threadUnexpectedException();
1283 }
1284 }
1285 });
1286
1287 try {
1288 t.start();
1289 Thread.sleep(SHORT_DELAY_MS);
1290 lock.writeLock().lock();
1291 assertTrue(lock.hasWaiters(c));
1292 assertEquals(1, lock.getWaitQueueLength(c));
1293 c.signal();
1294 lock.writeLock().unlock();
1295 Thread.sleep(SHORT_DELAY_MS);
1296 lock.writeLock().lock();
1297 assertFalse(lock.hasWaiters(c));
1298 assertEquals(0, lock.getWaitQueueLength(c));
1299 lock.writeLock().unlock();
1300 t.join(SHORT_DELAY_MS);
1301 assertFalse(t.isAlive());
1302 }
1303 catch (Exception ex) {
1304 unexpectedException();
1305 }
1306 }
1307
1308
1309 /**
1310 * getWaitingThreads returns only and all waiting threads
1311 */
1312 public void testGetWaitingThreads() {
1313 final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
1314 final Condition c = lock.writeLock().newCondition();
1315 Thread t1 = new Thread(new Runnable() {
1316 public void run() {
1317 try {
1318 lock.writeLock().lock();
1319 threadAssertTrue(lock.getWaitingThreads(c).isEmpty());
1320 c.await();
1321 lock.writeLock().unlock();
1322 }
1323 catch(InterruptedException e) {
1324 threadUnexpectedException();
1325 }
1326 }
1327 });
1328
1329 Thread t2 = new Thread(new Runnable() {
1330 public void run() {
1331 try {
1332 lock.writeLock().lock();
1333 threadAssertFalse(lock.getWaitingThreads(c).isEmpty());
1334 c.await();
1335 lock.writeLock().unlock();
1336 }
1337 catch(InterruptedException e) {
1338 threadUnexpectedException();
1339 }
1340 }
1341 });
1342
1343 try {
1344 lock.writeLock().lock();
1345 assertTrue(lock.getWaitingThreads(c).isEmpty());
1346 lock.writeLock().unlock();
1347 t1.start();
1348 Thread.sleep(SHORT_DELAY_MS);
1349 t2.start();
1350 Thread.sleep(SHORT_DELAY_MS);
1351 lock.writeLock().lock();
1352 assertTrue(lock.hasWaiters(c));
1353 assertTrue(lock.getWaitingThreads(c).contains(t1));
1354 assertTrue(lock.getWaitingThreads(c).contains(t2));
1355 c.signalAll();
1356 lock.writeLock().unlock();
1357 Thread.sleep(SHORT_DELAY_MS);
1358 lock.writeLock().lock();
1359 assertFalse(lock.hasWaiters(c));
1360 assertTrue(lock.getWaitingThreads(c).isEmpty());
1361 lock.writeLock().unlock();
1362 t1.join(SHORT_DELAY_MS);
1363 t2.join(SHORT_DELAY_MS);
1364 assertFalse(t1.isAlive());
1365 assertFalse(t2.isAlive());
1366 }
1367 catch (Exception ex) {
1368 unexpectedException();
1369 }
1370 }
1371
1372 /**
1373 * toString indicates current lock state
1374 */
1375 public void testToString() {
1376 ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1377 String us = lock.toString();
1378 assertTrue(us.indexOf("Write locks = 0") >= 0);
1379 assertTrue(us.indexOf("Read locks = 0") >= 0);
1380 lock.writeLock().lock();
1381 String ws = lock.toString();
1382 assertTrue(ws.indexOf("Write locks = 1") >= 0);
1383 assertTrue(ws.indexOf("Read locks = 0") >= 0);
1384 lock.writeLock().unlock();
1385 lock.readLock().lock();
1386 lock.readLock().lock();
1387 String rs = lock.toString();
1388 assertTrue(rs.indexOf("Write locks = 0") >= 0);
1389 assertTrue(rs.indexOf("Read locks = 2") >= 0);
1390 }
1391
1392 /**
1393 * readLock.toString indicates current lock state
1394 */
1395 public void testReadLockToString() {
1396 ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1397 String us = lock.readLock().toString();
1398 assertTrue(us.indexOf("Read locks = 0") >= 0);
1399 lock.readLock().lock();
1400 lock.readLock().lock();
1401 String rs = lock.readLock().toString();
1402 assertTrue(rs.indexOf("Read locks = 2") >= 0);
1403 }
1404
1405 /**
1406 * writeLock.toString indicates current lock state
1407 */
1408 public void testWriteLockToString() {
1409 ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1410 String us = lock.writeLock().toString();
1411 assertTrue(us.indexOf("Unlocked") >= 0);
1412 lock.writeLock().lock();
1413 String ls = lock.writeLock().toString();
1414 assertTrue(ls.indexOf("Locked") >= 0);
1415 }
1416
1417 }