ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ReentrantReadWriteLockTest.java
(Generate patch)

Comparing jsr166/src/test/tck/ReentrantReadWriteLockTest.java (file contents):
Revision 1.3 by dl, Sun Sep 14 20:42:40 2003 UTC vs.
Revision 1.23 by dl, Mon Aug 1 19:53:01 2005 UTC

# Line 1 | Line 1
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.
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) {
# Line 18 | Line 20 | public class ReentrantReadWriteLockTest
20          return new TestSuite(ReentrantReadWriteLockTest.class);
21      }
22  
23 <    static int HOLD_COUNT_TEST_LIMIT = 20;
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 <     * Unlocks an unlocked lock, throws Illegal Monitor State
38 <     *
36 >
37 >    /**
38 >     * A runnable calling lockInterruptibly that expects to be
39 >     * interrupted
40       */
41 <    public void testIllegalMonitorStateException(){
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 <        try{
71 <            rl.writeLock().unlock();
72 <            fail("Should of thown Illegal Monitor State Exception");
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 <        }catch(IllegalMonitorStateException success){}
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 testGetWriteHoldCount() {
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 +     * getReadHoldCount returns number of recursive holds
143 +     */
144 +    public void testGetReadHoldCount() {
145 +        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
146 +        for(int i = 1; i <= SIZE; i++) {
147 +            lock.readLock().lock();
148 +            assertEquals(i,lock.getReadHoldCount());
149 +        }
150 +        for(int i = SIZE; i > 0; i--) {
151 +            lock.readLock().unlock();
152 +            assertEquals(i-1,lock.getReadHoldCount());
153 +        }
154 +    }
155 +    
156 +
157 +    /**
158 +     * write-unlocking an unlocked lock throws IllegalMonitorStateException
159 +     */
160 +    public void testUnlock_IllegalMonitorStateException() {
161 +        ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
162 +        try {
163 +            rl.writeLock().unlock();
164 +            shouldThrow();
165 +        } catch(IllegalMonitorStateException success){}
166 +    }
167 +
168  
169 <    public void testInterruptedException(){
169 >    /**
170 >     * write-lockInterruptibly is interruptible
171 >     */
172 >    public void testWriteLockInterruptibly_Interrupted() {
173          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
40        lock.writeLock().lock();
174          Thread t = new Thread(new Runnable() {
175 <                public void run(){
176 <                    try{
175 >                public void run() {
176 >                    try {
177 >                        lock.writeLock().lockInterruptibly();
178 >                        lock.writeLock().unlock();
179                          lock.writeLock().lockInterruptibly();
180 <                        threadFail("should throw");
181 <                    }catch(InterruptedException success){}
180 >                        lock.writeLock().unlock();
181 >                    } catch(InterruptedException success){}
182                  }
183              });
184          try {
185 +            lock.writeLock().lock();
186              t.start();
187              t.interrupt();
188              lock.writeLock().unlock();
189              t.join();
190          } catch(Exception e){
191 <            fail("unexpected exception");
191 >            unexpectedException();
192          }
193      }
194  
195 <    public void testInterruptedException2(){
195 >    /**
196 >     * timed write-tryLock is interruptible
197 >     */
198 >    public void testWriteTryLock_Interrupted() {
199          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
200          lock.writeLock().lock();
201          Thread t = new Thread(new Runnable() {
202 <                public void run(){
203 <                    try{
202 >                public void run() {
203 >                    try {
204                          lock.writeLock().tryLock(1000,TimeUnit.MILLISECONDS);
205 <                        threadFail("should throw");
67 <                    }catch(InterruptedException success){}
205 >                    } catch(InterruptedException success){}
206                  }
207              });
208          try {
# Line 73 | Line 211 | public class ReentrantReadWriteLockTest
211              lock.writeLock().unlock();
212              t.join();
213          } catch(Exception e){
214 <            fail("unexpected exception");
214 >            unexpectedException();
215          }
216      }
217  
218 <    public void testInterruptedException3(){
218 >    /**
219 >     * read-lockInterruptibly is interruptible
220 >     */
221 >    public void testReadLockInterruptibly_Interrupted() {
222          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
223          lock.writeLock().lock();
224          Thread t = new Thread(new Runnable() {
225 <                public void run(){
226 <                    try{
225 >                public void run() {
226 >                    try {
227                          lock.readLock().lockInterruptibly();
228 <                        threadFail("should throw");
88 <                    }catch(InterruptedException success){}
228 >                    } catch(InterruptedException success){}
229                  }
230              });
231          try {
# Line 94 | Line 234 | public class ReentrantReadWriteLockTest
234              lock.writeLock().unlock();
235              t.join();
236          } catch(Exception e){
237 <            fail("unexpected exception");
237 >            unexpectedException();
238          }
239      }
240  
241 <    public void testInterruptedException4(){
241 >    /**
242 >     * timed read-tryLock is interruptible
243 >     */
244 >    public void testReadTryLock_Interrupted() {
245          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
246          lock.writeLock().lock();
247          Thread t = new Thread(new Runnable() {
248 <                public void run(){
249 <                    try{
248 >                public void run() {
249 >                    try {
250                          lock.readLock().tryLock(1000,TimeUnit.MILLISECONDS);
251 <                        threadFail("should throw");
252 <                    }catch(InterruptedException success){}
251 >                        threadShouldThrow();
252 >                    } catch(InterruptedException success){}
253                  }
254              });
255          try {
# Line 114 | Line 257 | public class ReentrantReadWriteLockTest
257              t.interrupt();
258              t.join();
259          } catch(Exception e){
260 <            fail("unexpected exception");
260 >            unexpectedException();
261          }
262      }
263  
264      
265 <    public void testTryLockWhenLocked() {
265 >    /**
266 >     * write-tryLock fails if locked
267 >     */
268 >    public void testWriteTryLockWhenLocked() {
269          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
270          lock.writeLock().lock();
271          Thread t = new Thread(new Runnable() {
272 <                public void run(){
272 >                public void run() {
273                      threadAssertFalse(lock.writeLock().tryLock());
274                  }
275              });
# Line 132 | Line 278 | public class ReentrantReadWriteLockTest
278              t.join();
279              lock.writeLock().unlock();
280          } catch(Exception e){
281 <            fail("unexpected exception");
281 >            unexpectedException();
282          }
283      }
284  
285 <    public void testTryLockWhenLocked2() {
285 >    /**
286 >     * read-tryLock fails if locked
287 >     */
288 >    public void testReadTryLockWhenLocked() {
289          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
290          lock.writeLock().lock();
291          Thread t = new Thread(new Runnable() {
292 <                public void run(){
292 >                public void run() {
293                      threadAssertFalse(lock.readLock().tryLock());
294                  }
295              });
# Line 149 | Line 298 | public class ReentrantReadWriteLockTest
298              t.join();
299              lock.writeLock().unlock();
300          } catch(Exception e){
301 <            fail("unexpected exception");
301 >            unexpectedException();
302          }
303      }
304  
305 +    /**
306 +     * Multiple threads can hold a read lock when not write-locked
307 +     */
308      public void testMultipleReadLocks() {
309          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
310          lock.readLock().lock();
311          Thread t = new Thread(new Runnable() {
312 <                public void run(){
312 >                public void run() {
313                      threadAssertTrue(lock.readLock().tryLock());
314                      lock.readLock().unlock();
315                  }
# Line 167 | Line 319 | public class ReentrantReadWriteLockTest
319              t.join();
320              lock.readLock().unlock();
321          } catch(Exception e){
322 <            fail("unexpected exception");
322 >            unexpectedException();
323          }
324      }
325  
326 +    /**
327 +     * A writelock succeeds after reading threads unlock
328 +     */
329      public void testWriteAfterMultipleReadLocks() {
330          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
331          lock.readLock().lock();
332          Thread t1 = new Thread(new Runnable() {
333 <                public void run(){
333 >                public void run() {
334                      lock.readLock().lock();
335                      lock.readLock().unlock();
336                  }
337              });
338          Thread t2 = new Thread(new Runnable() {
339 <                public void run(){
339 >                public void run() {
340                      lock.writeLock().lock();
341                      lock.writeLock().unlock();
342                  }
# Line 198 | Line 353 | public class ReentrantReadWriteLockTest
353              assertTrue(!t2.isAlive());
354            
355          } catch(Exception e){
356 <            fail("unexpected exception");
356 >            unexpectedException();
357          }
358      }
359  
360 +    /**
361 +     * Readlocks succeed after a writing thread unlocks
362 +     */
363      public void testReadAfterWriteLock() {
364          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
365          lock.writeLock().lock();
366          Thread t1 = new Thread(new Runnable() {
367 <                public void run(){
367 >                public void run() {
368                      lock.readLock().lock();
369                      lock.readLock().unlock();
370                  }
371              });
372          Thread t2 = new Thread(new Runnable() {
373 <                public void run(){
373 >                public void run() {
374                      lock.readLock().lock();
375                      lock.readLock().unlock();
376                  }
# Line 229 | Line 387 | public class ReentrantReadWriteLockTest
387              assertTrue(!t2.isAlive());
388            
389          } catch(Exception e){
390 <            fail("unexpected exception");
390 >            unexpectedException();
391          }
392      }
393  
394 +    /**
395 +     * Read trylock succeeds if write locked by current thread
396 +     */
397 +    public void testReadHoldingWriteLock() {
398 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
399 +        lock.writeLock().lock();
400 +        assertTrue(lock.readLock().tryLock());
401 +        lock.readLock().unlock();
402 +        lock.writeLock().unlock();
403 +    }
404 +
405 +    /**
406 +     * Read lock succeeds if write locked by current thread even if
407 +     * other threads are waiting for readlock
408 +     */
409 +    public void testReadHoldingWriteLock2() {
410 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
411 +        lock.writeLock().lock();
412 +        Thread t1 = new Thread(new Runnable() {
413 +                public void run() {
414 +                    lock.readLock().lock();
415 +                    lock.readLock().unlock();
416 +                }
417 +            });
418 +        Thread t2 = new Thread(new Runnable() {
419 +                public void run() {
420 +                    lock.readLock().lock();
421 +                    lock.readLock().unlock();
422 +                }
423 +            });
424  
425 +        try {
426 +            t1.start();
427 +            t2.start();
428 +            lock.readLock().lock();
429 +            lock.readLock().unlock();
430 +            Thread.sleep(SHORT_DELAY_MS);
431 +            lock.readLock().lock();
432 +            lock.readLock().unlock();
433 +            lock.writeLock().unlock();
434 +            t1.join(MEDIUM_DELAY_MS);
435 +            t2.join(MEDIUM_DELAY_MS);
436 +            assertTrue(!t1.isAlive());
437 +            assertTrue(!t2.isAlive());
438 +          
439 +        } catch(Exception e){
440 +            unexpectedException();
441 +        }
442 +    }
443 +
444 +    /**
445 +     *  Read lock succeeds if write locked by current thread even if
446 +     * other threads are waiting for writelock
447 +     */
448 +    public void testReadHoldingWriteLock3() {
449 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
450 +        lock.writeLock().lock();
451 +        Thread t1 = new Thread(new Runnable() {
452 +                public void run() {
453 +                    lock.writeLock().lock();
454 +                    lock.writeLock().unlock();
455 +                }
456 +            });
457 +        Thread t2 = new Thread(new Runnable() {
458 +                public void run() {
459 +                    lock.writeLock().lock();
460 +                    lock.writeLock().unlock();
461 +                }
462 +            });
463 +
464 +        try {
465 +            t1.start();
466 +            t2.start();
467 +            lock.readLock().lock();
468 +            lock.readLock().unlock();
469 +            Thread.sleep(SHORT_DELAY_MS);
470 +            lock.readLock().lock();
471 +            lock.readLock().unlock();
472 +            lock.writeLock().unlock();
473 +            t1.join(MEDIUM_DELAY_MS);
474 +            t2.join(MEDIUM_DELAY_MS);
475 +            assertTrue(!t1.isAlive());
476 +            assertTrue(!t2.isAlive());
477 +          
478 +        } catch(Exception e){
479 +            unexpectedException();
480 +        }
481 +    }
482 +
483 +
484 +    /**
485 +     *  Write lock succeeds if write locked by current thread even if
486 +     * other threads are waiting for writelock
487 +     */
488 +    public void testWriteHoldingWriteLock4() {
489 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
490 +        lock.writeLock().lock();
491 +        Thread t1 = new Thread(new Runnable() {
492 +                public void run() {
493 +                    lock.writeLock().lock();
494 +                    lock.writeLock().unlock();
495 +                }
496 +            });
497 +        Thread t2 = new Thread(new Runnable() {
498 +                public void run() {
499 +                    lock.writeLock().lock();
500 +                    lock.writeLock().unlock();
501 +                }
502 +            });
503 +
504 +        try {
505 +            t1.start();
506 +            t2.start();
507 +            lock.writeLock().lock();
508 +            lock.writeLock().unlock();
509 +            Thread.sleep(SHORT_DELAY_MS);
510 +            lock.writeLock().lock();
511 +            lock.writeLock().unlock();
512 +            lock.writeLock().unlock();
513 +            t1.join(MEDIUM_DELAY_MS);
514 +            t2.join(MEDIUM_DELAY_MS);
515 +            assertTrue(!t1.isAlive());
516 +            assertTrue(!t2.isAlive());
517 +          
518 +        } catch(Exception e){
519 +            unexpectedException();
520 +        }
521 +    }
522 +
523 +
524 +    /**
525 +     * Fair Read trylock succeeds if write locked by current thread
526 +     */
527 +    public void testReadHoldingWriteLockFair() {
528 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
529 +        lock.writeLock().lock();
530 +        assertTrue(lock.readLock().tryLock());
531 +        lock.readLock().unlock();
532 +        lock.writeLock().unlock();
533 +    }
534 +
535 +    /**
536 +     * Fair Read lock succeeds if write locked by current thread even if
537 +     * other threads are waiting for readlock
538 +     */
539 +    public void testReadHoldingWriteLockFair2() {
540 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
541 +        lock.writeLock().lock();
542 +        Thread t1 = new Thread(new Runnable() {
543 +                public void run() {
544 +                    lock.readLock().lock();
545 +                    lock.readLock().unlock();
546 +                }
547 +            });
548 +        Thread t2 = new Thread(new Runnable() {
549 +                public void run() {
550 +                    lock.readLock().lock();
551 +                    lock.readLock().unlock();
552 +                }
553 +            });
554 +
555 +        try {
556 +            t1.start();
557 +            t2.start();
558 +            lock.readLock().lock();
559 +            lock.readLock().unlock();
560 +            Thread.sleep(SHORT_DELAY_MS);
561 +            lock.readLock().lock();
562 +            lock.readLock().unlock();
563 +            lock.writeLock().unlock();
564 +            t1.join(MEDIUM_DELAY_MS);
565 +            t2.join(MEDIUM_DELAY_MS);
566 +            assertTrue(!t1.isAlive());
567 +            assertTrue(!t2.isAlive());
568 +          
569 +        } catch(Exception e){
570 +            unexpectedException();
571 +        }
572 +    }
573 +
574 +
575 +    /**
576 +     * Fair Read lock succeeds if write locked by current thread even if
577 +     * other threads are waiting for writelock
578 +     */
579 +    public void testReadHoldingWriteLockFair3() {
580 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
581 +        lock.writeLock().lock();
582 +        Thread t1 = new Thread(new Runnable() {
583 +                public void run() {
584 +                    lock.writeLock().lock();
585 +                    lock.writeLock().unlock();
586 +                }
587 +            });
588 +        Thread t2 = new Thread(new Runnable() {
589 +                public void run() {
590 +                    lock.writeLock().lock();
591 +                    lock.writeLock().unlock();
592 +                }
593 +            });
594 +
595 +        try {
596 +            t1.start();
597 +            t2.start();
598 +            lock.readLock().lock();
599 +            lock.readLock().unlock();
600 +            Thread.sleep(SHORT_DELAY_MS);
601 +            lock.readLock().lock();
602 +            lock.readLock().unlock();
603 +            lock.writeLock().unlock();
604 +            t1.join(MEDIUM_DELAY_MS);
605 +            t2.join(MEDIUM_DELAY_MS);
606 +            assertTrue(!t1.isAlive());
607 +            assertTrue(!t2.isAlive());
608 +          
609 +        } catch(Exception e){
610 +            unexpectedException();
611 +        }
612 +    }
613 +
614 +
615 +    /**
616 +     * Fair Write lock succeeds if write locked by current thread even if
617 +     * other threads are waiting for writelock
618 +     */
619 +    public void testWriteHoldingWriteLockFair4() {
620 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
621 +        lock.writeLock().lock();
622 +        Thread t1 = new Thread(new Runnable() {
623 +                public void run() {
624 +                    lock.writeLock().lock();
625 +                    lock.writeLock().unlock();
626 +                }
627 +            });
628 +        Thread t2 = new Thread(new Runnable() {
629 +                public void run() {
630 +                    lock.writeLock().lock();
631 +                    lock.writeLock().unlock();
632 +                }
633 +            });
634 +
635 +        try {
636 +            t1.start();
637 +            t2.start();
638 +            Thread.sleep(SHORT_DELAY_MS);
639 +            assertTrue(lock.isWriteLockedByCurrentThread());
640 +            assertTrue(lock.getWriteHoldCount() == 1);
641 +            lock.writeLock().lock();
642 +            assertTrue(lock.getWriteHoldCount() == 2);
643 +            lock.writeLock().unlock();
644 +            lock.writeLock().lock();
645 +            lock.writeLock().unlock();
646 +            lock.writeLock().unlock();
647 +            t1.join(MEDIUM_DELAY_MS);
648 +            t2.join(MEDIUM_DELAY_MS);
649 +            assertTrue(!t1.isAlive());
650 +            assertTrue(!t2.isAlive());
651 +          
652 +        } catch(Exception e){
653 +            unexpectedException();
654 +        }
655 +    }
656 +
657 +
658 +    /**
659 +     * Read tryLock succeeds if readlocked but not writelocked
660 +     */
661      public void testTryLockWhenReadLocked() {
662          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
663          lock.readLock().lock();
664          Thread t = new Thread(new Runnable() {
665 <                public void run(){
665 >                public void run() {
666                      threadAssertTrue(lock.readLock().tryLock());
667                      lock.readLock().unlock();
668                  }
# Line 248 | Line 672 | public class ReentrantReadWriteLockTest
672              t.join();
673              lock.readLock().unlock();
674          } catch(Exception e){
675 <            fail("unexpected exception");
675 >            unexpectedException();
676          }
677      }
678  
679      
680  
681 +    /**
682 +     * write tryLock fails when readlocked
683 +     */
684      public void testWriteTryLockWhenReadLocked() {
685          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
686          lock.readLock().lock();
687          Thread t = new Thread(new Runnable() {
688 <                public void run(){
688 >                public void run() {
689                      threadAssertFalse(lock.writeLock().tryLock());
690                  }
691              });
# Line 267 | Line 694 | public class ReentrantReadWriteLockTest
694              t.join();
695              lock.readLock().unlock();
696          } catch(Exception e){
697 <            fail("unexpected exception");
697 >            unexpectedException();
698          }
699      }
700  
701      
702  
703 <    public void testTryLock_Timeout(){
703 >    /**
704 >     * write timed tryLock times out if locked
705 >     */
706 >    public void testWriteTryLock_Timeout() {
707          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
708          lock.writeLock().lock();
709          Thread t = new Thread(new Runnable() {
710 <                public void run(){
710 >                public void run() {
711                      try {
712                          threadAssertFalse(lock.writeLock().tryLock(1, TimeUnit.MILLISECONDS));
713                      } catch (Exception ex) {
714 <                        threadFail("unexpected exception");
714 >                        threadUnexpectedException();
715                      }
716                  }
717              });
# Line 290 | Line 720 | public class ReentrantReadWriteLockTest
720              t.join();
721              lock.writeLock().unlock();
722          } catch(Exception e){
723 <            fail("unexpected exception");
723 >            unexpectedException();
724          }
725      }
726  
727 <    public void testTryLock_Timeout2(){
727 >    /**
728 >     * read timed tryLock times out if write-locked
729 >     */
730 >    public void testReadTryLock_Timeout() {
731          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
732          lock.writeLock().lock();
733          Thread t = new Thread(new Runnable() {
734 <                public void run(){
734 >                public void run() {
735                      try {
736                          threadAssertFalse(lock.readLock().tryLock(1, TimeUnit.MILLISECONDS));
737                      } catch (Exception ex) {
738 <                        threadFail("unexpected exception");
738 >                        threadUnexpectedException();
739                      }
740                  }
741              });
# Line 311 | Line 744 | public class ReentrantReadWriteLockTest
744              t.join();
745              lock.writeLock().unlock();
746          } catch(Exception e){
747 <            fail("unexpected exception");
747 >            unexpectedException();
748          }
749      }
750  
751  
752 <    public void testLockInterruptibly() {
752 >    /**
753 >     * write lockInterruptibly succeeds if lock free else is interruptible
754 >     */
755 >    public void testWriteLockInterruptibly() {
756          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
757          try {
758              lock.writeLock().lockInterruptibly();
759          } catch(Exception e) {
760 <            fail("unexpected exception");
760 >            unexpectedException();
761          }
762          Thread t = new Thread(new Runnable() {
763                  public void run() {
764                      try {
765                          lock.writeLock().lockInterruptibly();
766 <                        threadFail("should throw");
766 >                        threadShouldThrow();
767                      }
768                      catch(InterruptedException success) {
769                      }
# Line 339 | Line 775 | public class ReentrantReadWriteLockTest
775              t.join();
776              lock.writeLock().unlock();
777          } catch(Exception e){
778 <            fail("unexpected exception");
778 >            unexpectedException();
779          }
780      }
781  
782 <    public void testLockInterruptibly2() {
782 >    /**
783 >     *  read lockInterruptibly succeeds if lock free else is interruptible
784 >     */
785 >    public void testReadLockInterruptibly() {
786          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
787          try {
788              lock.writeLock().lockInterruptibly();
789          } catch(Exception e) {
790 <            fail("unexpected exception");
790 >            unexpectedException();
791          }
792          Thread t = new Thread(new Runnable() {
793                  public void run() {
794                      try {
795                          lock.readLock().lockInterruptibly();
796 <                        threadFail("should throw");
796 >                        threadShouldThrow();
797                      }
798                      catch(InterruptedException success) {
799                      }
# Line 366 | Line 805 | public class ReentrantReadWriteLockTest
805              t.join();
806              lock.writeLock().unlock();
807          } catch(Exception e){
808 <            fail("unexpected exception");
808 >            unexpectedException();
809          }
810      }
811  
812 +    /**
813 +     * Calling await without holding lock throws IllegalMonitorStateException
814 +     */
815      public void testAwait_IllegalMonitor() {
816          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
817          final Condition c = lock.writeLock().newCondition();
818          try {
819              c.await();
820 <            fail("should throw");
820 >            shouldThrow();
821          }
822          catch (IllegalMonitorStateException success) {
823          }
824          catch (Exception ex) {
825 <            fail("should throw IMSE");
825 >            shouldThrow();
826          }
827      }
828  
829 +    /**
830 +     * Calling signal without holding lock throws IllegalMonitorStateException
831 +     */
832      public void testSignal_IllegalMonitor() {
833          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
834          final Condition c = lock.writeLock().newCondition();
835          try {
836              c.signal();
837 <            fail("should throw");
837 >            shouldThrow();
838          }
839          catch (IllegalMonitorStateException success) {
840          }
841          catch (Exception ex) {
842 <            fail("should throw IMSE");
842 >            unexpectedException();
843          }
844      }
845  
846 +    /**
847 +     * awaitNanos without a signal times out
848 +     */
849      public void testAwaitNanos_Timeout() {
850          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
851          final Condition c = lock.writeLock().newCondition();
# Line 408 | Line 856 | public class ReentrantReadWriteLockTest
856              lock.writeLock().unlock();
857          }
858          catch (Exception ex) {
859 <            fail("unexpected exception");
859 >            unexpectedException();
860          }
861      }
862  
863 +
864 +    /**
865 +     *  timed await without a signal times out
866 +     */
867      public void testAwait_Timeout() {
868          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
869          final Condition c = lock.writeLock().newCondition();
870          try {
871              lock.writeLock().lock();
420            assertFalse(c.await(10, TimeUnit.MILLISECONDS));
872              lock.writeLock().unlock();
873          }
874          catch (Exception ex) {
875 <            fail("unexpected exception");
875 >            unexpectedException();
876          }
877      }
878  
879 +    /**
880 +     * awaitUntil without a signal times out
881 +     */
882      public void testAwaitUntil_Timeout() {
883          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
884          final Condition c = lock.writeLock().newCondition();
885          try {
886              lock.writeLock().lock();
887              java.util.Date d = new java.util.Date();
434            assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
888              lock.writeLock().unlock();
889          }
890          catch (Exception ex) {
891 <            fail("unexpected exception");
891 >            unexpectedException();
892          }
893      }
894  
895 +    /**
896 +     * await returns when signalled
897 +     */
898      public void testAwait() {
899          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
900          final Condition c = lock.writeLock().newCondition();
# Line 450 | Line 906 | public class ReentrantReadWriteLockTest
906                          lock.writeLock().unlock();
907                      }
908                      catch(InterruptedException e) {
909 <                        threadFail("unexpected exception");
909 >                        threadUnexpectedException();
910                      }
911                  }
912              });
# Line 465 | Line 921 | public class ReentrantReadWriteLockTest
921              assertFalse(t.isAlive());
922          }
923          catch (Exception ex) {
924 <            fail("unexpected exception");
924 >            unexpectedException();
925 >        }
926 >    }
927 >
928 >    /** A helper class for uninterruptible wait tests */
929 >    class UninterruptableThread extends Thread {
930 >        private Lock lock;
931 >        private Condition c;
932 >        
933 >        public volatile boolean canAwake = false;
934 >        public volatile boolean interrupted = false;
935 >        public volatile boolean lockStarted = false;
936 >        
937 >        public UninterruptableThread(Lock lock, Condition c) {
938 >            this.lock = lock;
939 >            this.c = c;
940 >        }
941 >        
942 >        public synchronized void run() {
943 >            lock.lock();
944 >            lockStarted = true;
945 >            
946 >            while (!canAwake) {
947 >                c.awaitUninterruptibly();
948 >            }
949 >            
950 >            interrupted = isInterrupted();
951 >            lock.unlock();
952          }
953      }
954  
955 +    /**
956 +     * awaitUninterruptibly doesn't abort on interrupt
957 +     */
958      public void testAwaitUninterruptibly() {
959 <        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
959 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
960          final Condition c = lock.writeLock().newCondition();
961 <        Thread t = new Thread(new Runnable() {
476 <                public void run() {
477 <                    lock.writeLock().lock();
478 <                    c.awaitUninterruptibly();
479 <                    lock.writeLock().unlock();
480 <                }
481 <            });
961 >        UninterruptableThread thread = new UninterruptableThread(lock.writeLock(), c);
962  
963          try {
964 <            t.start();
965 <            Thread.sleep(SHORT_DELAY_MS);
966 <            t.interrupt();
964 >            thread.start();
965 >
966 >            while (!thread.lockStarted) {
967 >                Thread.sleep(100);
968 >            }
969 >
970              lock.writeLock().lock();
971 <            c.signal();
972 <            lock.writeLock().unlock();
973 <            t.join(SHORT_DELAY_MS);
974 <            assertFalse(t.isAlive());
975 <        }
976 <        catch (Exception ex) {
977 <            fail("unexpected exception");
971 >            try {
972 >                thread.interrupt();
973 >                thread.canAwake = true;
974 >                c.signal();
975 >            } finally {
976 >                lock.writeLock().unlock();
977 >            }
978 >
979 >            thread.join();
980 >            assertTrue(thread.interrupted);
981 >            assertFalse(thread.isAlive());
982 >        } catch (Exception ex) {
983 >            unexpectedException();
984          }
985      }
986  
987 +    /**
988 +     * await is interruptible
989 +     */
990      public void testAwait_Interrupt() {
991          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
992          final Condition c = lock.writeLock().newCondition();
# Line 504 | Line 996 | public class ReentrantReadWriteLockTest
996                          lock.writeLock().lock();
997                          c.await();
998                          lock.writeLock().unlock();
999 <                        threadFail("should throw");
999 >                        threadShouldThrow();
1000                      }
1001                      catch(InterruptedException success) {
1002                      }
# Line 519 | Line 1011 | public class ReentrantReadWriteLockTest
1011              assertFalse(t.isAlive());
1012          }
1013          catch (Exception ex) {
1014 <            fail("unexpected exception");
1014 >            unexpectedException();
1015          }
1016      }
1017  
1018 +    /**
1019 +     * awaitNanos is interruptible
1020 +     */
1021      public void testAwaitNanos_Interrupt() {
1022          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
1023          final Condition c = lock.writeLock().newCondition();
# Line 532 | Line 1027 | public class ReentrantReadWriteLockTest
1027                          lock.writeLock().lock();
1028                          c.awaitNanos(SHORT_DELAY_MS * 2 * 1000000);
1029                          lock.writeLock().unlock();
1030 <                        threadFail("should throw");
1030 >                        threadShouldThrow();
1031                      }
1032                      catch(InterruptedException success) {
1033                      }
# Line 547 | Line 1042 | public class ReentrantReadWriteLockTest
1042              assertFalse(t.isAlive());
1043          }
1044          catch (Exception ex) {
1045 <            fail("unexpected exception");
1045 >            unexpectedException();
1046          }
1047      }
1048  
1049 +    /**
1050 +     * awaitUntil is interruptible
1051 +     */
1052      public void testAwaitUntil_Interrupt() {
1053          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
1054          final Condition c = lock.writeLock().newCondition();
# Line 561 | Line 1059 | public class ReentrantReadWriteLockTest
1059                          java.util.Date d = new java.util.Date();
1060                          c.awaitUntil(new java.util.Date(d.getTime() + 10000));
1061                          lock.writeLock().unlock();
1062 <                        threadFail("should throw");
1062 >                        threadShouldThrow();
1063                      }
1064                      catch(InterruptedException success) {
1065                      }
# Line 576 | Line 1074 | public class ReentrantReadWriteLockTest
1074              assertFalse(t.isAlive());
1075          }
1076          catch (Exception ex) {
1077 <            fail("unexpected exception");
1077 >            unexpectedException();
1078          }
1079      }
1080  
1081 +    /**
1082 +     * signalAll wakes up all threads
1083 +     */
1084      public void testSignalAll() {
1085          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
1086          final Condition c = lock.writeLock().newCondition();
# Line 591 | Line 1092 | public class ReentrantReadWriteLockTest
1092                          lock.writeLock().unlock();
1093                      }
1094                      catch(InterruptedException e) {
1095 <                        threadFail("unexpected exception");
1095 >                        threadUnexpectedException();
1096                      }
1097                  }
1098              });
# Line 604 | Line 1105 | public class ReentrantReadWriteLockTest
1105                          lock.writeLock().unlock();
1106                      }
1107                      catch(InterruptedException e) {
1108 <                        threadFail("unexpected exception");
1108 >                        threadUnexpectedException();
1109                      }
1110                  }
1111              });
# Line 622 | Line 1123 | public class ReentrantReadWriteLockTest
1123              assertFalse(t2.isAlive());
1124          }
1125          catch (Exception ex) {
1126 <            fail("unexpected exception");
1126 >            unexpectedException();
1127          }
1128      }
1129  
1130 +    /**
1131 +     * A serialized lock deserializes as unlocked
1132 +     */
1133      public void testSerialization() {
1134          ReentrantReadWriteLock l = new ReentrantReadWriteLock();
1135          l.readLock().lock();
# Line 644 | Line 1148 | public class ReentrantReadWriteLockTest
1148              r.readLock().unlock();
1149          } catch(Exception e){
1150              e.printStackTrace();
1151 <            fail("unexpected exception");
1151 >            unexpectedException();
1152 >        }
1153 >    }
1154 >
1155 >    /**
1156 >     * hasQueuedThreads reports whether there are waiting threads
1157 >     */
1158 >    public void testhasQueuedThreads() {
1159 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1160 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1161 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1162 >        try {
1163 >            assertFalse(lock.hasQueuedThreads());
1164 >            lock.writeLock().lock();
1165 >            t1.start();
1166 >            Thread.sleep(SHORT_DELAY_MS);
1167 >            assertTrue(lock.hasQueuedThreads());
1168 >            t2.start();
1169 >            Thread.sleep(SHORT_DELAY_MS);
1170 >            assertTrue(lock.hasQueuedThreads());
1171 >            t1.interrupt();
1172 >            Thread.sleep(SHORT_DELAY_MS);
1173 >            assertTrue(lock.hasQueuedThreads());
1174 >            lock.writeLock().unlock();
1175 >            Thread.sleep(SHORT_DELAY_MS);
1176 >            assertFalse(lock.hasQueuedThreads());
1177 >            t1.join();
1178 >            t2.join();
1179 >        } catch(Exception e){
1180 >            unexpectedException();
1181 >        }
1182 >    }
1183 >
1184 >    /**
1185 >     * hasQueuedThread(null) throws NPE
1186 >     */
1187 >    public void testHasQueuedThreadNPE() {
1188 >        final ReentrantReadWriteLock sync = new ReentrantReadWriteLock();
1189 >        try {
1190 >            sync.hasQueuedThread(null);
1191 >            shouldThrow();
1192 >        } catch (NullPointerException success) {
1193 >        }
1194 >    }
1195 >
1196 >    /**
1197 >     * hasQueuedThread reports whether a thread is queued.
1198 >     */
1199 >    public void testHasQueuedThread() {
1200 >        final ReentrantReadWriteLock sync = new ReentrantReadWriteLock();
1201 >        Thread t1 = new Thread(new InterruptedLockRunnable(sync));
1202 >        Thread t2 = new Thread(new InterruptibleLockRunnable(sync));
1203 >        try {
1204 >            assertFalse(sync.hasQueuedThread(t1));
1205 >            assertFalse(sync.hasQueuedThread(t2));
1206 >            sync.writeLock().lock();
1207 >            t1.start();
1208 >            Thread.sleep(SHORT_DELAY_MS);
1209 >            assertTrue(sync.hasQueuedThread(t1));
1210 >            t2.start();
1211 >            Thread.sleep(SHORT_DELAY_MS);
1212 >            assertTrue(sync.hasQueuedThread(t1));
1213 >            assertTrue(sync.hasQueuedThread(t2));
1214 >            t1.interrupt();
1215 >            Thread.sleep(SHORT_DELAY_MS);
1216 >            assertFalse(sync.hasQueuedThread(t1));
1217 >            assertTrue(sync.hasQueuedThread(t2));
1218 >            sync.writeLock().unlock();
1219 >            Thread.sleep(SHORT_DELAY_MS);
1220 >            assertFalse(sync.hasQueuedThread(t1));
1221 >            Thread.sleep(SHORT_DELAY_MS);
1222 >            assertFalse(sync.hasQueuedThread(t2));
1223 >            t1.join();
1224 >            t2.join();
1225 >        } catch(Exception e){
1226 >            unexpectedException();
1227 >        }
1228 >    }
1229 >
1230 >
1231 >    /**
1232 >     * getQueueLength reports number of waiting threads
1233 >     */
1234 >    public void testGetQueueLength() {
1235 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1236 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1237 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1238 >        try {
1239 >            assertEquals(0, lock.getQueueLength());
1240 >            lock.writeLock().lock();
1241 >            t1.start();
1242 >            Thread.sleep(SHORT_DELAY_MS);
1243 >            assertEquals(1, lock.getQueueLength());
1244 >            t2.start();
1245 >            Thread.sleep(SHORT_DELAY_MS);
1246 >            assertEquals(2, lock.getQueueLength());
1247 >            t1.interrupt();
1248 >            Thread.sleep(SHORT_DELAY_MS);
1249 >            assertEquals(1, lock.getQueueLength());
1250 >            lock.writeLock().unlock();
1251 >            Thread.sleep(SHORT_DELAY_MS);
1252 >            assertEquals(0, lock.getQueueLength());
1253 >            t1.join();
1254 >            t2.join();
1255 >        } catch(Exception e){
1256 >            unexpectedException();
1257 >        }
1258 >    }
1259 >
1260 >    /**
1261 >     * getQueuedThreads includes waiting threads
1262 >     */
1263 >    public void testGetQueuedThreads() {
1264 >        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
1265 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1266 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1267 >        try {
1268 >            assertTrue(lock.getQueuedThreads().isEmpty());
1269 >            lock.writeLock().lock();
1270 >            assertTrue(lock.getQueuedThreads().isEmpty());
1271 >            t1.start();
1272 >            Thread.sleep(SHORT_DELAY_MS);
1273 >            assertTrue(lock.getQueuedThreads().contains(t1));
1274 >            t2.start();
1275 >            Thread.sleep(SHORT_DELAY_MS);
1276 >            assertTrue(lock.getQueuedThreads().contains(t1));
1277 >            assertTrue(lock.getQueuedThreads().contains(t2));
1278 >            t1.interrupt();
1279 >            Thread.sleep(SHORT_DELAY_MS);
1280 >            assertFalse(lock.getQueuedThreads().contains(t1));
1281 >            assertTrue(lock.getQueuedThreads().contains(t2));
1282 >            lock.writeLock().unlock();
1283 >            Thread.sleep(SHORT_DELAY_MS);
1284 >            assertTrue(lock.getQueuedThreads().isEmpty());
1285 >            t1.join();
1286 >            t2.join();
1287 >        } catch(Exception e){
1288 >            unexpectedException();
1289 >        }
1290 >    }
1291 >
1292 >    /**
1293 >     * hasWaiters throws NPE if null
1294 >     */
1295 >    public void testHasWaitersNPE() {
1296 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1297 >        try {
1298 >            lock.hasWaiters(null);
1299 >            shouldThrow();
1300 >        } catch (NullPointerException success) {
1301 >        } catch (Exception ex) {
1302 >            unexpectedException();
1303 >        }
1304 >    }
1305 >
1306 >    /**
1307 >     * getWaitQueueLength throws NPE if null
1308 >     */
1309 >    public void testGetWaitQueueLengthNPE() {
1310 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1311 >        try {
1312 >            lock.getWaitQueueLength(null);
1313 >            shouldThrow();
1314 >        } catch (NullPointerException success) {
1315 >        } catch (Exception ex) {
1316 >            unexpectedException();
1317 >        }
1318 >    }
1319 >
1320 >
1321 >    /**
1322 >     * getWaitingThreads throws NPE if null
1323 >     */
1324 >    public void testGetWaitingThreadsNPE() {
1325 >        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
1326 >        try {
1327 >            lock.getWaitingThreads(null);
1328 >            shouldThrow();
1329 >        } catch (NullPointerException success) {
1330 >        } catch (Exception ex) {
1331 >            unexpectedException();
1332 >        }
1333 >    }
1334 >
1335 >    /**
1336 >     * hasWaiters throws IAE if not owned
1337 >     */
1338 >    public void testHasWaitersIAE() {
1339 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1340 >        final Condition c = (lock.writeLock().newCondition());
1341 >        final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock();
1342 >        try {
1343 >            lock2.hasWaiters(c);
1344 >            shouldThrow();
1345 >        } catch (IllegalArgumentException success) {
1346 >        } catch (Exception ex) {
1347 >            unexpectedException();
1348 >        }
1349 >    }
1350 >
1351 >    /**
1352 >     * hasWaiters throws IMSE if not locked
1353 >     */
1354 >    public void testHasWaitersIMSE() {
1355 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1356 >        final Condition c = (lock.writeLock().newCondition());
1357 >        try {
1358 >            lock.hasWaiters(c);
1359 >            shouldThrow();
1360 >        } catch (IllegalMonitorStateException success) {
1361 >        } catch (Exception ex) {
1362 >            unexpectedException();
1363 >        }
1364 >    }
1365 >
1366 >
1367 >    /**
1368 >     * getWaitQueueLength throws IAE if not owned
1369 >     */
1370 >    public void testGetWaitQueueLengthIAE() {
1371 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1372 >        final Condition c = (lock.writeLock().newCondition());
1373 >        final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock();
1374 >        try {
1375 >            lock2.getWaitQueueLength(c);
1376 >            shouldThrow();
1377 >        } catch (IllegalArgumentException success) {
1378 >        } catch (Exception ex) {
1379 >            unexpectedException();
1380 >        }
1381 >    }
1382 >
1383 >    /**
1384 >     * getWaitQueueLength throws IMSE if not locked
1385 >     */
1386 >    public void testGetWaitQueueLengthIMSE() {
1387 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1388 >        final Condition c = (lock.writeLock().newCondition());
1389 >        try {
1390 >            lock.getWaitQueueLength(c);
1391 >            shouldThrow();
1392 >        } catch (IllegalMonitorStateException success) {
1393 >        } catch (Exception ex) {
1394 >            unexpectedException();
1395 >        }
1396 >    }
1397 >
1398 >
1399 >    /**
1400 >     * getWaitingThreads throws IAE if not owned
1401 >     */
1402 >    public void testGetWaitingThreadsIAE() {
1403 >        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();  
1404 >        final Condition c = (lock.writeLock().newCondition());
1405 >        final PublicReentrantReadWriteLock lock2 = new PublicReentrantReadWriteLock();  
1406 >        try {
1407 >            lock2.getWaitingThreads(c);
1408 >            shouldThrow();
1409 >        } catch (IllegalArgumentException success) {
1410 >        } catch (Exception ex) {
1411 >            unexpectedException();
1412 >        }
1413 >    }
1414 >
1415 >    /**
1416 >     * getWaitingThreads throws IMSE if not locked
1417 >     */
1418 >    public void testGetWaitingThreadsIMSE() {
1419 >        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();  
1420 >        final Condition c = (lock.writeLock().newCondition());
1421 >        try {
1422 >            lock.getWaitingThreads(c);
1423 >            shouldThrow();
1424 >        } catch (IllegalMonitorStateException success) {
1425 >        } catch (Exception ex) {
1426 >            unexpectedException();
1427 >        }
1428 >    }
1429 >
1430 >
1431 >    /**
1432 >     * hasWaiters returns true when a thread is waiting, else false
1433 >     */
1434 >    public void testHasWaiters() {
1435 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1436 >        final Condition c = (lock.writeLock().newCondition());
1437 >        Thread t = new Thread(new Runnable() {
1438 >                public void run() {
1439 >                    try {
1440 >                        lock.writeLock().lock();
1441 >                        threadAssertFalse(lock.hasWaiters(c));
1442 >                        threadAssertEquals(0, lock.getWaitQueueLength(c));
1443 >                        c.await();
1444 >                        lock.writeLock().unlock();
1445 >                    }
1446 >                    catch(InterruptedException e) {
1447 >                        threadUnexpectedException();
1448 >                    }
1449 >                }
1450 >            });
1451 >
1452 >        try {
1453 >            t.start();
1454 >            Thread.sleep(SHORT_DELAY_MS);
1455 >            lock.writeLock().lock();
1456 >            assertTrue(lock.hasWaiters(c));
1457 >            assertEquals(1, lock.getWaitQueueLength(c));
1458 >            c.signal();
1459 >            lock.writeLock().unlock();
1460 >            Thread.sleep(SHORT_DELAY_MS);
1461 >            lock.writeLock().lock();
1462 >            assertFalse(lock.hasWaiters(c));
1463 >            assertEquals(0, lock.getWaitQueueLength(c));
1464 >            lock.writeLock().unlock();
1465 >            t.join(SHORT_DELAY_MS);
1466 >            assertFalse(t.isAlive());
1467 >        }
1468 >        catch (Exception ex) {
1469 >            unexpectedException();
1470 >        }
1471 >    }
1472 >
1473 >    /**
1474 >     * getWaitQueueLength returns number of waiting threads
1475 >     */
1476 >    public void testGetWaitQueueLength() {
1477 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1478 >        final Condition c = (lock.writeLock().newCondition());
1479 >        Thread t = new Thread(new Runnable() {
1480 >                public void run() {
1481 >                    try {
1482 >                        lock.writeLock().lock();
1483 >                        threadAssertFalse(lock.hasWaiters(c));
1484 >                        threadAssertEquals(0, lock.getWaitQueueLength(c));
1485 >                        c.await();
1486 >                        lock.writeLock().unlock();
1487 >                    }
1488 >                    catch(InterruptedException e) {
1489 >                        threadUnexpectedException();
1490 >                    }
1491 >                }
1492 >            });
1493 >
1494 >        try {
1495 >            t.start();
1496 >            Thread.sleep(SHORT_DELAY_MS);
1497 >            lock.writeLock().lock();
1498 >            assertTrue(lock.hasWaiters(c));
1499 >            assertEquals(1, lock.getWaitQueueLength(c));
1500 >            c.signal();
1501 >            lock.writeLock().unlock();
1502 >            Thread.sleep(SHORT_DELAY_MS);
1503 >            lock.writeLock().lock();
1504 >            assertFalse(lock.hasWaiters(c));
1505 >            assertEquals(0, lock.getWaitQueueLength(c));
1506 >            lock.writeLock().unlock();
1507 >            t.join(SHORT_DELAY_MS);
1508 >            assertFalse(t.isAlive());
1509 >        }
1510 >        catch (Exception ex) {
1511 >            unexpectedException();
1512 >        }
1513 >    }
1514 >
1515 >
1516 >    /**
1517 >     * getWaitingThreads returns only and all waiting threads
1518 >     */
1519 >    public void testGetWaitingThreads() {
1520 >        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();  
1521 >        final Condition c = lock.writeLock().newCondition();
1522 >        Thread t1 = new Thread(new Runnable() {
1523 >                public void run() {
1524 >                    try {
1525 >                        lock.writeLock().lock();
1526 >                        threadAssertTrue(lock.getWaitingThreads(c).isEmpty());
1527 >                        c.await();
1528 >                        lock.writeLock().unlock();
1529 >                    }
1530 >                    catch(InterruptedException e) {
1531 >                        threadUnexpectedException();
1532 >                    }
1533 >                }
1534 >            });
1535 >
1536 >        Thread t2 = new Thread(new Runnable() {
1537 >                public void run() {
1538 >                    try {
1539 >                        lock.writeLock().lock();
1540 >                        threadAssertFalse(lock.getWaitingThreads(c).isEmpty());
1541 >                        c.await();
1542 >                        lock.writeLock().unlock();
1543 >                    }
1544 >                    catch(InterruptedException e) {
1545 >                        threadUnexpectedException();
1546 >                    }
1547 >                }
1548 >            });
1549 >
1550 >        try {
1551 >            lock.writeLock().lock();
1552 >            assertTrue(lock.getWaitingThreads(c).isEmpty());
1553 >            lock.writeLock().unlock();
1554 >            t1.start();
1555 >            Thread.sleep(SHORT_DELAY_MS);
1556 >            t2.start();
1557 >            Thread.sleep(SHORT_DELAY_MS);
1558 >            lock.writeLock().lock();
1559 >            assertTrue(lock.hasWaiters(c));
1560 >            assertTrue(lock.getWaitingThreads(c).contains(t1));
1561 >            assertTrue(lock.getWaitingThreads(c).contains(t2));
1562 >            c.signalAll();
1563 >            lock.writeLock().unlock();
1564 >            Thread.sleep(SHORT_DELAY_MS);
1565 >            lock.writeLock().lock();
1566 >            assertFalse(lock.hasWaiters(c));
1567 >            assertTrue(lock.getWaitingThreads(c).isEmpty());
1568 >            lock.writeLock().unlock();
1569 >            t1.join(SHORT_DELAY_MS);
1570 >            t2.join(SHORT_DELAY_MS);
1571 >            assertFalse(t1.isAlive());
1572 >            assertFalse(t2.isAlive());
1573 >        }
1574 >        catch (Exception ex) {
1575 >            unexpectedException();
1576          }
1577      }
1578  
1579 +    /**
1580 +     * toString indicates current lock state
1581 +     */
1582 +    public void testToString() {
1583 +        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1584 +        String us = lock.toString();
1585 +        assertTrue(us.indexOf("Write locks = 0") >= 0);
1586 +        assertTrue(us.indexOf("Read locks = 0") >= 0);
1587 +        lock.writeLock().lock();
1588 +        String ws = lock.toString();
1589 +        assertTrue(ws.indexOf("Write locks = 1") >= 0);
1590 +        assertTrue(ws.indexOf("Read locks = 0") >= 0);
1591 +        lock.writeLock().unlock();
1592 +        lock.readLock().lock();
1593 +        lock.readLock().lock();
1594 +        String rs = lock.toString();
1595 +        assertTrue(rs.indexOf("Write locks = 0") >= 0);
1596 +        assertTrue(rs.indexOf("Read locks = 2") >= 0);
1597 +    }
1598 +
1599 +    /**
1600 +     * readLock.toString indicates current lock state
1601 +     */
1602 +    public void testReadLockToString() {
1603 +        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1604 +        String us = lock.readLock().toString();
1605 +        assertTrue(us.indexOf("Read locks = 0") >= 0);
1606 +        lock.readLock().lock();
1607 +        lock.readLock().lock();
1608 +        String rs = lock.readLock().toString();
1609 +        assertTrue(rs.indexOf("Read locks = 2") >= 0);
1610 +    }
1611 +
1612 +    /**
1613 +     * writeLock.toString indicates current lock state
1614 +     */
1615 +    public void testWriteLockToString() {
1616 +        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1617 +        String us = lock.writeLock().toString();
1618 +        assertTrue(us.indexOf("Unlocked") >= 0);
1619 +        lock.writeLock().lock();
1620 +        String ls = lock.writeLock().toString();
1621 +        assertTrue(ls.indexOf("Locked") >= 0);
1622 +    }
1623  
1624   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines