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.2 by dl, Sun Sep 7 20:39:11 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 TestCase {
14 <    static int HOLD_COUNT_TEST_LIMIT = 20;
15 <    
15 > public class ReentrantReadWriteLockTest extends JSR166TestCase {
16      public static void main(String[] args) {
17          junit.textui.TestRunner.run (suite());  
18      }
19    
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 <    private static long SHORT_DELAY_MS = 100;
37 <    private static long MEDIUM_DELAY_MS = 1000;
38 <    private static long LONG_DELAY_MS = 10000;
39 <
29 <    /*
30 <     * Unlocks an unlocked lock, throws Illegal Monitor State
31 <     *
36 >
37 >    /**
38 >     * A runnable calling lockInterruptibly that expects to be
39 >     * interrupted
40       */
41 <    
42 <    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 >    /**
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 <        }catch(IllegalMonitorStateException success){}
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 <    public void testInterruptedException(){
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 >    /**
170 >     * write-lockInterruptibly is interruptible
171 >     */
172 >    public void testWriteLockInterruptibly_Interrupted() {
173          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
47        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 <                        fail("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 <                        fail("should throw");
74 <                    }catch(InterruptedException success){}
205 >                    } catch(InterruptedException success){}
206                  }
207              });
208          try {
# Line 80 | 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 <                        fail("should throw");
95 <                    }catch(InterruptedException success){}
228 >                    } catch(InterruptedException success){}
229                  }
230              });
231          try {
# Line 101 | 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 <                        fail("should throw");
252 <                    }catch(InterruptedException success){}
251 >                        threadShouldThrow();
252 >                    } catch(InterruptedException success){}
253                  }
254              });
255          try {
# Line 121 | 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(){
273 <                    assertFalse(lock.writeLock().tryLock());
272 >                public void run() {
273 >                    threadAssertFalse(lock.writeLock().tryLock());
274                  }
275              });
276          try {
# Line 139 | 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(){
293 <                    assertFalse(lock.readLock().tryLock());
292 >                public void run() {
293 >                    threadAssertFalse(lock.readLock().tryLock());
294                  }
295              });
296          try {
# Line 156 | 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(){
313 <                    assertTrue(lock.readLock().tryLock());
312 >                public void run() {
313 >                    threadAssertTrue(lock.readLock().tryLock());
314                      lock.readLock().unlock();
315                  }
316              });
# Line 174 | 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 205 | 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() {
374 >                    lock.readLock().lock();
375 >                    lock.readLock().unlock();
376 >                }
377 >            });
378 >
379 >        try {
380 >            t1.start();
381 >            t2.start();
382 >            Thread.sleep(SHORT_DELAY_MS);
383 >            lock.writeLock().unlock();
384 >            t1.join(MEDIUM_DELAY_MS);
385 >            t2.join(MEDIUM_DELAY_MS);
386 >            assertTrue(!t1.isAlive());
387 >            assertTrue(!t2.isAlive());
388 >          
389 >        } catch(Exception e){
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(){
549 >                public void run() {
550                      lock.readLock().lock();
551                      lock.readLock().unlock();
552                  }
# Line 228 | Line 555 | public class ReentrantReadWriteLockTest
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);
# Line 236 | Line 567 | public class ReentrantReadWriteLockTest
567              assertTrue(!t2.isAlive());
568            
569          } catch(Exception e){
570 <            fail("unexpected exception");
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(){
666 <                    assertTrue(lock.readLock().tryLock());
665 >                public void run() {
666 >                    threadAssertTrue(lock.readLock().tryLock());
667                      lock.readLock().unlock();
668                  }
669              });
# Line 255 | 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(){
689 <                    assertFalse(lock.writeLock().tryLock());
688 >                public void run() {
689 >                    threadAssertFalse(lock.writeLock().tryLock());
690                  }
691              });
692          try {
# Line 274 | 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 <                        assertFalse(lock.writeLock().tryLock(1, TimeUnit.MILLISECONDS));
712 >                        threadAssertFalse(lock.writeLock().tryLock(1, TimeUnit.MILLISECONDS));
713                      } catch (Exception ex) {
714 <                        fail("unexpected exception");
714 >                        threadUnexpectedException();
715                      }
716                  }
717              });
# Line 297 | 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 <                        assertFalse(lock.readLock().tryLock(1, TimeUnit.MILLISECONDS));
736 >                        threadAssertFalse(lock.readLock().tryLock(1, TimeUnit.MILLISECONDS));
737                      } catch (Exception ex) {
738 <                        fail("unexpected exception");
738 >                        threadUnexpectedException();
739                      }
740                  }
741              });
# Line 318 | 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 <                        fail("should throw");
766 >                        threadShouldThrow();
767                      }
768                      catch(InterruptedException success) {
769                      }
# Line 346 | 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 <                        fail("should throw");
796 >                        threadShouldThrow();
797                      }
798                      catch(InterruptedException success) {
799                      }
# Line 373 | 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 415 | 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();
427            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();
441            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 457 | Line 906 | public class ReentrantReadWriteLockTest
906                          lock.writeLock().unlock();
907                      }
908                      catch(InterruptedException e) {
909 <                        fail("unexpected exception");
909 >                        threadUnexpectedException();
910                      }
911                  }
912              });
# Line 472 | 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() {
483 <                public void run() {
484 <                    lock.writeLock().lock();
485 <                    c.awaitUninterruptibly();
486 <                    lock.writeLock().unlock();
487 <                }
488 <            });
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 511 | Line 996 | public class ReentrantReadWriteLockTest
996                          lock.writeLock().lock();
997                          c.await();
998                          lock.writeLock().unlock();
999 <                        fail("should throw");
999 >                        threadShouldThrow();
1000                      }
1001                      catch(InterruptedException success) {
1002                      }
# Line 526 | 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 539 | Line 1027 | public class ReentrantReadWriteLockTest
1027                          lock.writeLock().lock();
1028                          c.awaitNanos(SHORT_DELAY_MS * 2 * 1000000);
1029                          lock.writeLock().unlock();
1030 <                        fail("should throw");
1030 >                        threadShouldThrow();
1031                      }
1032                      catch(InterruptedException success) {
1033                      }
# Line 554 | 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 568 | 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 <                        fail("should throw");
1062 >                        threadShouldThrow();
1063                      }
1064                      catch(InterruptedException success) {
1065                      }
# Line 583 | 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 598 | Line 1092 | public class ReentrantReadWriteLockTest
1092                          lock.writeLock().unlock();
1093                      }
1094                      catch(InterruptedException e) {
1095 <                        fail("unexpected exception");
1095 >                        threadUnexpectedException();
1096                      }
1097                  }
1098              });
# Line 611 | Line 1105 | public class ReentrantReadWriteLockTest
1105                          lock.writeLock().unlock();
1106                      }
1107                      catch(InterruptedException e) {
1108 <                        fail("unexpected exception");
1108 >                        threadUnexpectedException();
1109                      }
1110                  }
1111              });
# Line 629 | 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 651 | 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