ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ReentrantReadWriteLockTest.java
Revision: 1.11
Committed: Sat Dec 27 18:27:02 2003 UTC (20 years, 4 months ago) by dl
Branch: MAIN
Changes since 1.10: +2 -77 lines
Log Message:
Adjust protected method tests

File Contents

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