ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ReentrantReadWriteLockTest.java
Revision: 1.22
Committed: Tue May 3 16:02:00 2005 UTC (19 years ago) by dl
Branch: MAIN
Changes since 1.21: +47 -18 lines
Log Message:
Fix some asserts and awaitUninterruptibly tests

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