ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ReentrantReadWriteLockTest.java
Revision: 1.12
Committed: Sat Dec 27 19:26:43 2003 UTC (20 years, 4 months ago) by dl
Branch: MAIN
Changes since 1.11: +5 -4 lines
Log Message:
Headers reference Creative Commons

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 }
61
62 /**
63 * Constructor sets given fairness, and is in unlocked state
64 */
65 public void testConstructor() {
66 ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
67 assertFalse(rl.isFair());
68 assertFalse(rl.isWriteLocked());
69 assertEquals(0, rl.getReadLockCount());
70 ReentrantReadWriteLock r2 = new ReentrantReadWriteLock(true);
71 assertTrue(r2.isFair());
72 assertFalse(r2.isWriteLocked());
73 assertEquals(0, r2.getReadLockCount());
74 }
75
76 /**
77 * write-locking and read-locking an unlocked lock succeed
78 */
79 public void testLock() {
80 ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
81 rl.writeLock().lock();
82 assertTrue(rl.isWriteLocked());
83 assertTrue(rl.isWriteLockedByCurrentThread());
84 assertEquals(0, rl.getReadLockCount());
85 rl.writeLock().unlock();
86 assertFalse(rl.isWriteLocked());
87 assertFalse(rl.isWriteLockedByCurrentThread());
88 assertEquals(0, rl.getReadLockCount());
89 rl.readLock().lock();
90 assertFalse(rl.isWriteLocked());
91 assertFalse(rl.isWriteLockedByCurrentThread());
92 assertEquals(1, rl.getReadLockCount());
93 rl.readLock().unlock();
94 assertFalse(rl.isWriteLocked());
95 assertFalse(rl.isWriteLockedByCurrentThread());
96 assertEquals(0, rl.getReadLockCount());
97 }
98
99
100 /**
101 * locking an unlocked fair lock succeeds
102 */
103 public void testFairLock() {
104 ReentrantReadWriteLock rl = new ReentrantReadWriteLock(true);
105 rl.writeLock().lock();
106 assertTrue(rl.isWriteLocked());
107 assertTrue(rl.isWriteLockedByCurrentThread());
108 assertEquals(0, rl.getReadLockCount());
109 rl.writeLock().unlock();
110 assertFalse(rl.isWriteLocked());
111 assertFalse(rl.isWriteLockedByCurrentThread());
112 assertEquals(0, rl.getReadLockCount());
113 rl.readLock().lock();
114 assertFalse(rl.isWriteLocked());
115 assertFalse(rl.isWriteLockedByCurrentThread());
116 assertEquals(1, rl.getReadLockCount());
117 rl.readLock().unlock();
118 assertFalse(rl.isWriteLocked());
119 assertFalse(rl.isWriteLockedByCurrentThread());
120 assertEquals(0, rl.getReadLockCount());
121 }
122
123 /**
124 * getWriteHoldCount returns number of recursive holds
125 */
126 public void testGetHoldCount() {
127 ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
128 for(int i = 1; i <= SIZE; i++) {
129 lock.writeLock().lock();
130 assertEquals(i,lock.getWriteHoldCount());
131 }
132 for(int i = SIZE; i > 0; i--) {
133 lock.writeLock().unlock();
134 assertEquals(i-1,lock.getWriteHoldCount());
135 }
136 }
137
138
139 /**
140 * write-unlocking an unlocked lock throws IllegalMonitorStateException
141 */
142 public void testUnlock_IllegalMonitorStateException() {
143 ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
144 try {
145 rl.writeLock().unlock();
146 shouldThrow();
147 } catch(IllegalMonitorStateException success){}
148 }
149
150
151 /**
152 * write-lockInterruptibly is interruptible
153 */
154 public void testWriteLockInterruptibly_Interrupted() {
155 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
156 lock.writeLock().lock();
157 Thread t = new Thread(new Runnable() {
158 public void run() {
159 try {
160 lock.writeLock().lockInterruptibly();
161 threadShouldThrow();
162 } catch(InterruptedException success){}
163 }
164 });
165 try {
166 t.start();
167 t.interrupt();
168 lock.writeLock().unlock();
169 t.join();
170 } catch(Exception e){
171 unexpectedException();
172 }
173 }
174
175 /**
176 * timed write-trylock is interruptible
177 */
178 public void testWriteTryLock_Interrupted() {
179 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
180 lock.writeLock().lock();
181 Thread t = new Thread(new Runnable() {
182 public void run() {
183 try {
184 lock.writeLock().tryLock(1000,TimeUnit.MILLISECONDS);
185 threadShouldThrow();
186 } catch(InterruptedException success){}
187 }
188 });
189 try {
190 t.start();
191 t.interrupt();
192 lock.writeLock().unlock();
193 t.join();
194 } catch(Exception e){
195 unexpectedException();
196 }
197 }
198
199 /**
200 * read-lockInterruptibly is interruptible
201 */
202 public void testReadLockInterruptibly_Interrupted() {
203 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
204 lock.writeLock().lock();
205 Thread t = new Thread(new Runnable() {
206 public void run() {
207 try {
208 lock.readLock().lockInterruptibly();
209 threadShouldThrow();
210 } catch(InterruptedException success){}
211 }
212 });
213 try {
214 t.start();
215 t.interrupt();
216 lock.writeLock().unlock();
217 t.join();
218 } catch(Exception e){
219 unexpectedException();
220 }
221 }
222
223 /**
224 * timed read-trylock is interruptible
225 */
226 public void testReadTryLock_Interrupted() {
227 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
228 lock.writeLock().lock();
229 Thread t = new Thread(new Runnable() {
230 public void run() {
231 try {
232 lock.readLock().tryLock(1000,TimeUnit.MILLISECONDS);
233 threadShouldThrow();
234 } catch(InterruptedException success){}
235 }
236 });
237 try {
238 t.start();
239 t.interrupt();
240 t.join();
241 } catch(Exception e){
242 unexpectedException();
243 }
244 }
245
246
247 /**
248 * write-trylock fails if locked
249 */
250 public void testWriteTryLockWhenLocked() {
251 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
252 lock.writeLock().lock();
253 Thread t = new Thread(new Runnable() {
254 public void run() {
255 threadAssertFalse(lock.writeLock().tryLock());
256 }
257 });
258 try {
259 t.start();
260 t.join();
261 lock.writeLock().unlock();
262 } catch(Exception e){
263 unexpectedException();
264 }
265 }
266
267 /**
268 * read-trylock fails if locked
269 */
270 public void testReadTryLockWhenLocked() {
271 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
272 lock.writeLock().lock();
273 Thread t = new Thread(new Runnable() {
274 public void run() {
275 threadAssertFalse(lock.readLock().tryLock());
276 }
277 });
278 try {
279 t.start();
280 t.join();
281 lock.writeLock().unlock();
282 } catch(Exception e){
283 unexpectedException();
284 }
285 }
286
287 /**
288 * Multiple threads can hold a read lock when not write-locked
289 */
290 public void testMultipleReadLocks() {
291 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
292 lock.readLock().lock();
293 Thread t = new Thread(new Runnable() {
294 public void run() {
295 threadAssertTrue(lock.readLock().tryLock());
296 lock.readLock().unlock();
297 }
298 });
299 try {
300 t.start();
301 t.join();
302 lock.readLock().unlock();
303 } catch(Exception e){
304 unexpectedException();
305 }
306 }
307
308 /**
309 * A writelock succeeds after reading threads unlock
310 */
311 public void testWriteAfterMultipleReadLocks() {
312 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
313 lock.readLock().lock();
314 Thread t1 = new Thread(new Runnable() {
315 public void run() {
316 lock.readLock().lock();
317 lock.readLock().unlock();
318 }
319 });
320 Thread t2 = new Thread(new Runnable() {
321 public void run() {
322 lock.writeLock().lock();
323 lock.writeLock().unlock();
324 }
325 });
326
327 try {
328 t1.start();
329 t2.start();
330 Thread.sleep(SHORT_DELAY_MS);
331 lock.readLock().unlock();
332 t1.join(MEDIUM_DELAY_MS);
333 t2.join(MEDIUM_DELAY_MS);
334 assertTrue(!t1.isAlive());
335 assertTrue(!t2.isAlive());
336
337 } catch(Exception e){
338 unexpectedException();
339 }
340 }
341
342 /**
343 * Readlocks succeed after a writing thread unlocks
344 */
345 public void testReadAfterWriteLock() {
346 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
347 lock.writeLock().lock();
348 Thread t1 = new Thread(new Runnable() {
349 public void run() {
350 lock.readLock().lock();
351 lock.readLock().unlock();
352 }
353 });
354 Thread t2 = new Thread(new Runnable() {
355 public void run() {
356 lock.readLock().lock();
357 lock.readLock().unlock();
358 }
359 });
360
361 try {
362 t1.start();
363 t2.start();
364 Thread.sleep(SHORT_DELAY_MS);
365 lock.writeLock().unlock();
366 t1.join(MEDIUM_DELAY_MS);
367 t2.join(MEDIUM_DELAY_MS);
368 assertTrue(!t1.isAlive());
369 assertTrue(!t2.isAlive());
370
371 } catch(Exception e){
372 unexpectedException();
373 }
374 }
375
376
377 /**
378 * Read trylock succeeds if readlocked but not writelocked
379 */
380 public void testTryLockWhenReadLocked() {
381 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
382 lock.readLock().lock();
383 Thread t = new Thread(new Runnable() {
384 public void run() {
385 threadAssertTrue(lock.readLock().tryLock());
386 lock.readLock().unlock();
387 }
388 });
389 try {
390 t.start();
391 t.join();
392 lock.readLock().unlock();
393 } catch(Exception e){
394 unexpectedException();
395 }
396 }
397
398
399
400 /**
401 * write trylock fails when readlocked
402 */
403 public void testWriteTryLockWhenReadLocked() {
404 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
405 lock.readLock().lock();
406 Thread t = new Thread(new Runnable() {
407 public void run() {
408 threadAssertFalse(lock.writeLock().tryLock());
409 }
410 });
411 try {
412 t.start();
413 t.join();
414 lock.readLock().unlock();
415 } catch(Exception e){
416 unexpectedException();
417 }
418 }
419
420
421
422 /**
423 * write timed trylock times out if locked
424 */
425 public void testWriteTryLock_Timeout() {
426 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
427 lock.writeLock().lock();
428 Thread t = new Thread(new Runnable() {
429 public void run() {
430 try {
431 threadAssertFalse(lock.writeLock().tryLock(1, TimeUnit.MILLISECONDS));
432 } catch (Exception ex) {
433 threadUnexpectedException();
434 }
435 }
436 });
437 try {
438 t.start();
439 t.join();
440 lock.writeLock().unlock();
441 } catch(Exception e){
442 unexpectedException();
443 }
444 }
445
446 /**
447 * read timed trylock times out if write-locked
448 */
449 public void testReadTryLock_Timeout() {
450 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
451 lock.writeLock().lock();
452 Thread t = new Thread(new Runnable() {
453 public void run() {
454 try {
455 threadAssertFalse(lock.readLock().tryLock(1, TimeUnit.MILLISECONDS));
456 } catch (Exception ex) {
457 threadUnexpectedException();
458 }
459 }
460 });
461 try {
462 t.start();
463 t.join();
464 lock.writeLock().unlock();
465 } catch(Exception e){
466 unexpectedException();
467 }
468 }
469
470
471 /**
472 * write lockInterruptibly succeeds if lock free else is interruptible
473 */
474 public void testWriteLockInterruptibly() {
475 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
476 try {
477 lock.writeLock().lockInterruptibly();
478 } catch(Exception e) {
479 unexpectedException();
480 }
481 Thread t = new Thread(new Runnable() {
482 public void run() {
483 try {
484 lock.writeLock().lockInterruptibly();
485 threadShouldThrow();
486 }
487 catch(InterruptedException success) {
488 }
489 }
490 });
491 try {
492 t.start();
493 t.interrupt();
494 t.join();
495 lock.writeLock().unlock();
496 } catch(Exception e){
497 unexpectedException();
498 }
499 }
500
501 /**
502 * read lockInterruptibly succeeds if lock free else is interruptible
503 */
504 public void testReadLockInterruptibly() {
505 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
506 try {
507 lock.writeLock().lockInterruptibly();
508 } catch(Exception e) {
509 unexpectedException();
510 }
511 Thread t = new Thread(new Runnable() {
512 public void run() {
513 try {
514 lock.readLock().lockInterruptibly();
515 threadShouldThrow();
516 }
517 catch(InterruptedException success) {
518 }
519 }
520 });
521 try {
522 t.start();
523 t.interrupt();
524 t.join();
525 lock.writeLock().unlock();
526 } catch(Exception e){
527 unexpectedException();
528 }
529 }
530
531 /**
532 * Calling await without holding lock throws IllegalMonitorStateException
533 */
534 public void testAwait_IllegalMonitor() {
535 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
536 final Condition c = lock.writeLock().newCondition();
537 try {
538 c.await();
539 shouldThrow();
540 }
541 catch (IllegalMonitorStateException success) {
542 }
543 catch (Exception ex) {
544 shouldThrow();
545 }
546 }
547
548 /**
549 * Calling signal without holding lock throws IllegalMonitorStateException
550 */
551 public void testSignal_IllegalMonitor() {
552 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
553 final Condition c = lock.writeLock().newCondition();
554 try {
555 c.signal();
556 shouldThrow();
557 }
558 catch (IllegalMonitorStateException success) {
559 }
560 catch (Exception ex) {
561 unexpectedException();
562 }
563 }
564
565 /**
566 * awaitNanos without a signal times out
567 */
568 public void testAwaitNanos_Timeout() {
569 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
570 final Condition c = lock.writeLock().newCondition();
571 try {
572 lock.writeLock().lock();
573 long t = c.awaitNanos(100);
574 assertTrue(t <= 0);
575 lock.writeLock().unlock();
576 }
577 catch (Exception ex) {
578 unexpectedException();
579 }
580 }
581
582
583 /**
584 * timed await without a signal times out
585 */
586 public void testAwait_Timeout() {
587 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
588 final Condition c = lock.writeLock().newCondition();
589 try {
590 lock.writeLock().lock();
591 assertFalse(c.await(10, TimeUnit.MILLISECONDS));
592 lock.writeLock().unlock();
593 }
594 catch (Exception ex) {
595 unexpectedException();
596 }
597 }
598
599 /**
600 * awaitUntil without a signal times out
601 */
602 public void testAwaitUntil_Timeout() {
603 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
604 final Condition c = lock.writeLock().newCondition();
605 try {
606 lock.writeLock().lock();
607 java.util.Date d = new java.util.Date();
608 assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
609 lock.writeLock().unlock();
610 }
611 catch (Exception ex) {
612 unexpectedException();
613 }
614 }
615
616 /**
617 * await returns when signalled
618 */
619 public void testAwait() {
620 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
621 final Condition c = lock.writeLock().newCondition();
622 Thread t = new Thread(new Runnable() {
623 public void run() {
624 try {
625 lock.writeLock().lock();
626 c.await();
627 lock.writeLock().unlock();
628 }
629 catch(InterruptedException e) {
630 threadUnexpectedException();
631 }
632 }
633 });
634
635 try {
636 t.start();
637 Thread.sleep(SHORT_DELAY_MS);
638 lock.writeLock().lock();
639 c.signal();
640 lock.writeLock().unlock();
641 t.join(SHORT_DELAY_MS);
642 assertFalse(t.isAlive());
643 }
644 catch (Exception ex) {
645 unexpectedException();
646 }
647 }
648
649 /**
650 * awaitUninterruptibly doesn't abort on interrupt
651 */
652 public void testAwaitUninterruptibly() {
653 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
654 final Condition c = lock.writeLock().newCondition();
655 Thread t = new Thread(new Runnable() {
656 public void run() {
657 lock.writeLock().lock();
658 c.awaitUninterruptibly();
659 lock.writeLock().unlock();
660 }
661 });
662
663 try {
664 t.start();
665 Thread.sleep(SHORT_DELAY_MS);
666 t.interrupt();
667 lock.writeLock().lock();
668 c.signal();
669 lock.writeLock().unlock();
670 assert(t.isInterrupted());
671 t.join(SHORT_DELAY_MS);
672 assertFalse(t.isAlive());
673 }
674 catch (Exception ex) {
675 unexpectedException();
676 }
677 }
678
679 /**
680 * await is interruptible
681 */
682 public void testAwait_Interrupt() {
683 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
684 final Condition c = lock.writeLock().newCondition();
685 Thread t = new Thread(new Runnable() {
686 public void run() {
687 try {
688 lock.writeLock().lock();
689 c.await();
690 lock.writeLock().unlock();
691 threadShouldThrow();
692 }
693 catch(InterruptedException success) {
694 }
695 }
696 });
697
698 try {
699 t.start();
700 Thread.sleep(SHORT_DELAY_MS);
701 t.interrupt();
702 t.join(SHORT_DELAY_MS);
703 assertFalse(t.isAlive());
704 }
705 catch (Exception ex) {
706 unexpectedException();
707 }
708 }
709
710 /**
711 * awaitNanos is interruptible
712 */
713 public void testAwaitNanos_Interrupt() {
714 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
715 final Condition c = lock.writeLock().newCondition();
716 Thread t = new Thread(new Runnable() {
717 public void run() {
718 try {
719 lock.writeLock().lock();
720 c.awaitNanos(SHORT_DELAY_MS * 2 * 1000000);
721 lock.writeLock().unlock();
722 threadShouldThrow();
723 }
724 catch(InterruptedException success) {
725 }
726 }
727 });
728
729 try {
730 t.start();
731 Thread.sleep(SHORT_DELAY_MS);
732 t.interrupt();
733 t.join(SHORT_DELAY_MS);
734 assertFalse(t.isAlive());
735 }
736 catch (Exception ex) {
737 unexpectedException();
738 }
739 }
740
741 /**
742 * awaitUntil is interruptible
743 */
744 public void testAwaitUntil_Interrupt() {
745 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
746 final Condition c = lock.writeLock().newCondition();
747 Thread t = new Thread(new Runnable() {
748 public void run() {
749 try {
750 lock.writeLock().lock();
751 java.util.Date d = new java.util.Date();
752 c.awaitUntil(new java.util.Date(d.getTime() + 10000));
753 lock.writeLock().unlock();
754 threadShouldThrow();
755 }
756 catch(InterruptedException success) {
757 }
758 }
759 });
760
761 try {
762 t.start();
763 Thread.sleep(SHORT_DELAY_MS);
764 t.interrupt();
765 t.join(SHORT_DELAY_MS);
766 assertFalse(t.isAlive());
767 }
768 catch (Exception ex) {
769 unexpectedException();
770 }
771 }
772
773 /**
774 * signalAll wakes up all threads
775 */
776 public void testSignalAll() {
777 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
778 final Condition c = lock.writeLock().newCondition();
779 Thread t1 = new Thread(new Runnable() {
780 public void run() {
781 try {
782 lock.writeLock().lock();
783 c.await();
784 lock.writeLock().unlock();
785 }
786 catch(InterruptedException e) {
787 threadUnexpectedException();
788 }
789 }
790 });
791
792 Thread t2 = new Thread(new Runnable() {
793 public void run() {
794 try {
795 lock.writeLock().lock();
796 c.await();
797 lock.writeLock().unlock();
798 }
799 catch(InterruptedException e) {
800 threadUnexpectedException();
801 }
802 }
803 });
804
805 try {
806 t1.start();
807 t2.start();
808 Thread.sleep(SHORT_DELAY_MS);
809 lock.writeLock().lock();
810 c.signalAll();
811 lock.writeLock().unlock();
812 t1.join(SHORT_DELAY_MS);
813 t2.join(SHORT_DELAY_MS);
814 assertFalse(t1.isAlive());
815 assertFalse(t2.isAlive());
816 }
817 catch (Exception ex) {
818 unexpectedException();
819 }
820 }
821
822 /**
823 * A serialized lock deserializes as unlocked
824 */
825 public void testSerialization() {
826 ReentrantReadWriteLock l = new ReentrantReadWriteLock();
827 l.readLock().lock();
828 l.readLock().unlock();
829
830 try {
831 ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
832 ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
833 out.writeObject(l);
834 out.close();
835
836 ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
837 ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
838 ReentrantReadWriteLock r = (ReentrantReadWriteLock) in.readObject();
839 r.readLock().lock();
840 r.readLock().unlock();
841 } catch(Exception e){
842 e.printStackTrace();
843 unexpectedException();
844 }
845 }
846
847 /**
848 * getQueueLength reports number of waiting threads
849 */
850 public void testGetQueueLength() {
851 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
852 Thread t1 = new Thread(new InterruptedLockRunnable(lock));
853 Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
854 try {
855 assertEquals(0, lock.getQueueLength());
856 lock.writeLock().lock();
857 t1.start();
858 Thread.sleep(SHORT_DELAY_MS);
859 assertEquals(1, lock.getQueueLength());
860 t2.start();
861 Thread.sleep(SHORT_DELAY_MS);
862 assertEquals(2, lock.getQueueLength());
863 t1.interrupt();
864 Thread.sleep(SHORT_DELAY_MS);
865 assertEquals(1, lock.getQueueLength());
866 lock.writeLock().unlock();
867 Thread.sleep(SHORT_DELAY_MS);
868 assertEquals(0, lock.getQueueLength());
869 t1.join();
870 t2.join();
871 } catch(Exception e){
872 unexpectedException();
873 }
874 }
875
876 /**
877 * getQueuedThreads includes waiting threads
878 */
879 public void testGetQueuedThreads() {
880 final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
881 Thread t1 = new Thread(new InterruptedLockRunnable(lock));
882 Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
883 try {
884 assertTrue(lock.getQueuedThreads().isEmpty());
885 lock.writeLock().lock();
886 assertTrue(lock.getQueuedThreads().isEmpty());
887 t1.start();
888 Thread.sleep(SHORT_DELAY_MS);
889 assertTrue(lock.getQueuedThreads().contains(t1));
890 t2.start();
891 Thread.sleep(SHORT_DELAY_MS);
892 assertTrue(lock.getQueuedThreads().contains(t1));
893 assertTrue(lock.getQueuedThreads().contains(t2));
894 t1.interrupt();
895 Thread.sleep(SHORT_DELAY_MS);
896 assertFalse(lock.getQueuedThreads().contains(t1));
897 assertTrue(lock.getQueuedThreads().contains(t2));
898 lock.writeLock().unlock();
899 Thread.sleep(SHORT_DELAY_MS);
900 assertTrue(lock.getQueuedThreads().isEmpty());
901 t1.join();
902 t2.join();
903 } catch(Exception e){
904 unexpectedException();
905 }
906 }
907
908 /**
909 * hasWaiters returns true when a thread is waiting, else false
910 */
911 public void testHasWaiters() {
912 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
913 final AbstractQueuedSynchronizer.ConditionObject c = (lock.writeLock().newCondition());
914 Thread t = new Thread(new Runnable() {
915 public void run() {
916 try {
917 lock.writeLock().lock();
918 threadAssertFalse(c.hasWaiters());
919 threadAssertEquals(0, c.getWaitQueueLength());
920 c.await();
921 lock.writeLock().unlock();
922 }
923 catch(InterruptedException e) {
924 threadUnexpectedException();
925 }
926 }
927 });
928
929 try {
930 t.start();
931 Thread.sleep(SHORT_DELAY_MS);
932 lock.writeLock().lock();
933 assertTrue(c.hasWaiters());
934 assertEquals(1, c.getWaitQueueLength());
935 c.signal();
936 lock.writeLock().unlock();
937 Thread.sleep(SHORT_DELAY_MS);
938 lock.writeLock().lock();
939 assertFalse(c.hasWaiters());
940 assertEquals(0, c.getWaitQueueLength());
941 lock.writeLock().unlock();
942 t.join(SHORT_DELAY_MS);
943 assertFalse(t.isAlive());
944 }
945 catch (Exception ex) {
946 unexpectedException();
947 }
948 }
949
950 /**
951 * getWaitQueueLength returns number of waiting threads
952 */
953 public void testGetWaitQueueLength() {
954 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
955 final AbstractQueuedSynchronizer.ConditionObject c = (lock.writeLock().newCondition());
956 Thread t1 = new Thread(new Runnable() {
957 public void run() {
958 try {
959 lock.writeLock().lock();
960 threadAssertFalse(c.hasWaiters());
961 threadAssertEquals(0, c.getWaitQueueLength());
962 c.await();
963 lock.writeLock().unlock();
964 }
965 catch(InterruptedException e) {
966 threadUnexpectedException();
967 }
968 }
969 });
970
971 Thread t2 = new Thread(new Runnable() {
972 public void run() {
973 try {
974 lock.writeLock().lock();
975 threadAssertTrue(c.hasWaiters());
976 threadAssertEquals(1, c.getWaitQueueLength());
977 c.await();
978 lock.writeLock().unlock();
979 }
980 catch(InterruptedException e) {
981 threadUnexpectedException();
982 }
983 }
984 });
985
986 try {
987 t1.start();
988 Thread.sleep(SHORT_DELAY_MS);
989 t2.start();
990 Thread.sleep(SHORT_DELAY_MS);
991 lock.writeLock().lock();
992 assertTrue(c.hasWaiters());
993 assertEquals(2, c.getWaitQueueLength());
994 c.signalAll();
995 lock.writeLock().unlock();
996 Thread.sleep(SHORT_DELAY_MS);
997 lock.writeLock().lock();
998 assertFalse(c.hasWaiters());
999 assertEquals(0, c.getWaitQueueLength());
1000 lock.writeLock().unlock();
1001 t1.join(SHORT_DELAY_MS);
1002 t2.join(SHORT_DELAY_MS);
1003 assertFalse(t1.isAlive());
1004 assertFalse(t2.isAlive());
1005 }
1006 catch (Exception ex) {
1007 unexpectedException();
1008 }
1009 }
1010 }