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.25 by dl, Sun Jan 29 21:17:38 2006 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 >    /**
38 >     * A runnable calling lockInterruptibly that expects to be
39 >     * interrupted
40 >     */
41 >    class InterruptedLockRunnable implements Runnable {
42 >        final ReentrantReadWriteLock lock;
43 >        InterruptedLockRunnable(ReentrantReadWriteLock l) { lock = l; }
44 >        public void run() {
45 >            try {
46 >                lock.writeLock().lockInterruptibly();
47 >                threadShouldThrow();
48 >            } catch(InterruptedException success){}
49 >        }
50 >    }
51 >
52 >    /**
53 >     * Subclass to expose protected methods
54 >     */
55 >    static class PublicReentrantReadWriteLock extends ReentrantReadWriteLock {
56 >        PublicReentrantReadWriteLock() { super(); }
57 >        public Collection<Thread> getQueuedThreads() {
58 >            return super.getQueuedThreads();
59 >        }
60 >        public Collection<Thread> getWaitingThreads(Condition c) {
61 >            return super.getWaitingThreads(c);
62 >        }
63 >    }
64  
65 <    /*
66 <     * Unlocks an unlocked lock, throws Illegal Monitor State
25 <     *
65 >    /**
66 >     * Constructor sets given fairness, and is in unlocked state
67       */
68 <    public void testIllegalMonitorStateException(){
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 >        assertTrue(rl.writeLock().isHeldByCurrentThread());
88 >        assertEquals(0, rl.getReadLockCount());
89 >        rl.writeLock().unlock();
90 >        assertFalse(rl.isWriteLocked());
91 >        assertFalse(rl.isWriteLockedByCurrentThread());
92 >        assertFalse(rl.writeLock().isHeldByCurrentThread());
93 >        assertEquals(0, rl.getReadLockCount());
94 >        rl.readLock().lock();
95 >        assertFalse(rl.isWriteLocked());
96 >        assertFalse(rl.isWriteLockedByCurrentThread());
97 >        assertEquals(1, rl.getReadLockCount());
98 >        rl.readLock().unlock();
99 >        assertFalse(rl.isWriteLocked());
100 >        assertFalse(rl.isWriteLockedByCurrentThread());
101 >        assertEquals(0, rl.getReadLockCount());
102      }
103  
104  
105 +    /**
106 +     * locking an unlocked fair lock succeeds
107 +     */
108 +    public void testFairLock() {
109 +        ReentrantReadWriteLock rl = new ReentrantReadWriteLock(true);
110 +        rl.writeLock().lock();
111 +        assertTrue(rl.isWriteLocked());
112 +        assertTrue(rl.isWriteLockedByCurrentThread());
113 +        assertTrue(rl.writeLock().isHeldByCurrentThread());
114 +        assertEquals(0, rl.getReadLockCount());
115 +        rl.writeLock().unlock();
116 +        assertFalse(rl.isWriteLocked());
117 +        assertFalse(rl.isWriteLockedByCurrentThread());
118 +        assertFalse(rl.writeLock().isHeldByCurrentThread());
119 +        assertEquals(0, rl.getReadLockCount());
120 +        rl.readLock().lock();
121 +        assertFalse(rl.isWriteLocked());
122 +        assertFalse(rl.isWriteLockedByCurrentThread());
123 +        assertEquals(1, rl.getReadLockCount());
124 +        rl.readLock().unlock();
125 +        assertFalse(rl.isWriteLocked());
126 +        assertFalse(rl.isWriteLockedByCurrentThread());
127 +        assertEquals(0, rl.getReadLockCount());
128 +    }
129 +
130 +    /**
131 +     * getWriteHoldCount returns number of recursive holds
132 +     */
133 +    public void testGetWriteHoldCount() {
134 +        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
135 +        for(int i = 1; i <= SIZE; i++) {
136 +            lock.writeLock().lock();
137 +            assertEquals(i,lock.getWriteHoldCount());
138 +        }
139 +        for(int i = SIZE; i > 0; i--) {
140 +            lock.writeLock().unlock();
141 +            assertEquals(i-1,lock.getWriteHoldCount());
142 +        }
143 +    }
144 +
145 +    /**
146 +     * WriteLock.getHoldCount returns number of recursive holds
147 +     */
148 +    public void testGetHoldCount() {
149 +        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
150 +        for(int i = 1; i <= SIZE; i++) {
151 +            lock.writeLock().lock();
152 +            assertEquals(i,lock.writeLock().getHoldCount());
153 +        }
154 +        for(int i = SIZE; i > 0; i--) {
155 +            lock.writeLock().unlock();
156 +            assertEquals(i-1,lock.writeLock().getHoldCount());
157 +        }
158 +    }
159 +
160 +    /**
161 +     * getReadHoldCount returns number of recursive holds
162 +     */
163 +    public void testGetReadHoldCount() {
164 +        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
165 +        for(int i = 1; i <= SIZE; i++) {
166 +            lock.readLock().lock();
167 +            assertEquals(i,lock.getReadHoldCount());
168 +        }
169 +        for(int i = SIZE; i > 0; i--) {
170 +            lock.readLock().unlock();
171 +            assertEquals(i-1,lock.getReadHoldCount());
172 +        }
173 +    }
174 +    
175 +
176 +    /**
177 +     * write-unlocking an unlocked lock throws IllegalMonitorStateException
178 +     */
179 +    public void testUnlock_IllegalMonitorStateException() {
180 +        ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
181 +        try {
182 +            rl.writeLock().unlock();
183 +            shouldThrow();
184 +        } catch(IllegalMonitorStateException success){}
185 +    }
186  
187 <    public void testInterruptedException(){
187 >
188 >    /**
189 >     * write-lockInterruptibly is interruptible
190 >     */
191 >    public void testWriteLockInterruptibly_Interrupted() {
192          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
40        lock.writeLock().lock();
193          Thread t = new Thread(new Runnable() {
194 <                public void run(){
195 <                    try{
194 >                public void run() {
195 >                    try {
196 >                        lock.writeLock().lockInterruptibly();
197 >                        lock.writeLock().unlock();
198                          lock.writeLock().lockInterruptibly();
199 <                        threadFail("should throw");
200 <                    }catch(InterruptedException success){}
199 >                        lock.writeLock().unlock();
200 >                    } catch(InterruptedException success){}
201                  }
202              });
203          try {
204 +            lock.writeLock().lock();
205              t.start();
206              t.interrupt();
207              lock.writeLock().unlock();
208              t.join();
209          } catch(Exception e){
210 <            fail("unexpected exception");
210 >            unexpectedException();
211          }
212      }
213  
214 <    public void testInterruptedException2(){
214 >    /**
215 >     * timed write-tryLock is interruptible
216 >     */
217 >    public void testWriteTryLock_Interrupted() {
218          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
219          lock.writeLock().lock();
220          Thread t = new Thread(new Runnable() {
221 <                public void run(){
222 <                    try{
221 >                public void run() {
222 >                    try {
223                          lock.writeLock().tryLock(1000,TimeUnit.MILLISECONDS);
224 <                        threadFail("should throw");
67 <                    }catch(InterruptedException success){}
224 >                    } catch(InterruptedException success){}
225                  }
226              });
227          try {
# Line 73 | Line 230 | public class ReentrantReadWriteLockTest
230              lock.writeLock().unlock();
231              t.join();
232          } catch(Exception e){
233 <            fail("unexpected exception");
233 >            unexpectedException();
234          }
235      }
236  
237 <    public void testInterruptedException3(){
237 >    /**
238 >     * read-lockInterruptibly is interruptible
239 >     */
240 >    public void testReadLockInterruptibly_Interrupted() {
241          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
242          lock.writeLock().lock();
243          Thread t = new Thread(new Runnable() {
244 <                public void run(){
245 <                    try{
244 >                public void run() {
245 >                    try {
246                          lock.readLock().lockInterruptibly();
247 <                        threadFail("should throw");
88 <                    }catch(InterruptedException success){}
247 >                    } catch(InterruptedException success){}
248                  }
249              });
250          try {
# Line 94 | Line 253 | public class ReentrantReadWriteLockTest
253              lock.writeLock().unlock();
254              t.join();
255          } catch(Exception e){
256 <            fail("unexpected exception");
256 >            unexpectedException();
257          }
258      }
259  
260 <    public void testInterruptedException4(){
260 >    /**
261 >     * timed read-tryLock is interruptible
262 >     */
263 >    public void testReadTryLock_Interrupted() {
264          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
265          lock.writeLock().lock();
266          Thread t = new Thread(new Runnable() {
267 <                public void run(){
268 <                    try{
267 >                public void run() {
268 >                    try {
269                          lock.readLock().tryLock(1000,TimeUnit.MILLISECONDS);
270 <                        threadFail("should throw");
271 <                    }catch(InterruptedException success){}
270 >                        threadShouldThrow();
271 >                    } catch(InterruptedException success){}
272                  }
273              });
274          try {
# Line 114 | Line 276 | public class ReentrantReadWriteLockTest
276              t.interrupt();
277              t.join();
278          } catch(Exception e){
279 <            fail("unexpected exception");
279 >            unexpectedException();
280          }
281      }
282  
283      
284 <    public void testTryLockWhenLocked() {
284 >    /**
285 >     * write-tryLock fails if locked
286 >     */
287 >    public void testWriteTryLockWhenLocked() {
288          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
289          lock.writeLock().lock();
290          Thread t = new Thread(new Runnable() {
291 <                public void run(){
291 >                public void run() {
292                      threadAssertFalse(lock.writeLock().tryLock());
293                  }
294              });
# Line 132 | Line 297 | public class ReentrantReadWriteLockTest
297              t.join();
298              lock.writeLock().unlock();
299          } catch(Exception e){
300 <            fail("unexpected exception");
300 >            unexpectedException();
301          }
302      }
303  
304 <    public void testTryLockWhenLocked2() {
304 >    /**
305 >     * read-tryLock fails if locked
306 >     */
307 >    public void testReadTryLockWhenLocked() {
308          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
309          lock.writeLock().lock();
310          Thread t = new Thread(new Runnable() {
311 <                public void run(){
311 >                public void run() {
312                      threadAssertFalse(lock.readLock().tryLock());
313                  }
314              });
# Line 149 | Line 317 | public class ReentrantReadWriteLockTest
317              t.join();
318              lock.writeLock().unlock();
319          } catch(Exception e){
320 <            fail("unexpected exception");
320 >            unexpectedException();
321          }
322      }
323  
324 +    /**
325 +     * Multiple threads can hold a read lock when not write-locked
326 +     */
327      public void testMultipleReadLocks() {
328          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
329          lock.readLock().lock();
330          Thread t = new Thread(new Runnable() {
331 <                public void run(){
331 >                public void run() {
332                      threadAssertTrue(lock.readLock().tryLock());
333                      lock.readLock().unlock();
334                  }
# Line 167 | Line 338 | public class ReentrantReadWriteLockTest
338              t.join();
339              lock.readLock().unlock();
340          } catch(Exception e){
341 <            fail("unexpected exception");
341 >            unexpectedException();
342          }
343      }
344  
345 +    /**
346 +     * A writelock succeeds after reading threads unlock
347 +     */
348      public void testWriteAfterMultipleReadLocks() {
349          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
350          lock.readLock().lock();
351          Thread t1 = new Thread(new Runnable() {
352 <                public void run(){
352 >                public void run() {
353                      lock.readLock().lock();
354                      lock.readLock().unlock();
355                  }
356              });
357          Thread t2 = new Thread(new Runnable() {
358 <                public void run(){
358 >                public void run() {
359                      lock.writeLock().lock();
360                      lock.writeLock().unlock();
361                  }
# Line 198 | Line 372 | public class ReentrantReadWriteLockTest
372              assertTrue(!t2.isAlive());
373            
374          } catch(Exception e){
375 <            fail("unexpected exception");
375 >            unexpectedException();
376          }
377      }
378  
379 +    /**
380 +     * Readlocks succeed after a writing thread unlocks
381 +     */
382      public void testReadAfterWriteLock() {
383          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
384          lock.writeLock().lock();
385          Thread t1 = new Thread(new Runnable() {
386 <                public void run(){
386 >                public void run() {
387 >                    lock.readLock().lock();
388 >                    lock.readLock().unlock();
389 >                }
390 >            });
391 >        Thread t2 = new Thread(new Runnable() {
392 >                public void run() {
393 >                    lock.readLock().lock();
394 >                    lock.readLock().unlock();
395 >                }
396 >            });
397 >
398 >        try {
399 >            t1.start();
400 >            t2.start();
401 >            Thread.sleep(SHORT_DELAY_MS);
402 >            lock.writeLock().unlock();
403 >            t1.join(MEDIUM_DELAY_MS);
404 >            t2.join(MEDIUM_DELAY_MS);
405 >            assertTrue(!t1.isAlive());
406 >            assertTrue(!t2.isAlive());
407 >          
408 >        } catch(Exception e){
409 >            unexpectedException();
410 >        }
411 >    }
412 >
413 >    /**
414 >     * Read trylock succeeds if write locked by current thread
415 >     */
416 >    public void testReadHoldingWriteLock() {
417 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
418 >        lock.writeLock().lock();
419 >        assertTrue(lock.readLock().tryLock());
420 >        lock.readLock().unlock();
421 >        lock.writeLock().unlock();
422 >    }
423 >
424 >    /**
425 >     * Read lock succeeds if write locked by current thread even if
426 >     * other threads are waiting for readlock
427 >     */
428 >    public void testReadHoldingWriteLock2() {
429 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
430 >        lock.writeLock().lock();
431 >        Thread t1 = new Thread(new Runnable() {
432 >                public void run() {
433 >                    lock.readLock().lock();
434 >                    lock.readLock().unlock();
435 >                }
436 >            });
437 >        Thread t2 = new Thread(new Runnable() {
438 >                public void run() {
439 >                    lock.readLock().lock();
440 >                    lock.readLock().unlock();
441 >                }
442 >            });
443 >
444 >        try {
445 >            t1.start();
446 >            t2.start();
447 >            lock.readLock().lock();
448 >            lock.readLock().unlock();
449 >            Thread.sleep(SHORT_DELAY_MS);
450 >            lock.readLock().lock();
451 >            lock.readLock().unlock();
452 >            lock.writeLock().unlock();
453 >            t1.join(MEDIUM_DELAY_MS);
454 >            t2.join(MEDIUM_DELAY_MS);
455 >            assertTrue(!t1.isAlive());
456 >            assertTrue(!t2.isAlive());
457 >          
458 >        } catch(Exception e){
459 >            unexpectedException();
460 >        }
461 >    }
462 >
463 >    /**
464 >     *  Read lock succeeds if write locked by current thread even if
465 >     * other threads are waiting for writelock
466 >     */
467 >    public void testReadHoldingWriteLock3() {
468 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
469 >        lock.writeLock().lock();
470 >        Thread t1 = new Thread(new Runnable() {
471 >                public void run() {
472 >                    lock.writeLock().lock();
473 >                    lock.writeLock().unlock();
474 >                }
475 >            });
476 >        Thread t2 = new Thread(new Runnable() {
477 >                public void run() {
478 >                    lock.writeLock().lock();
479 >                    lock.writeLock().unlock();
480 >                }
481 >            });
482 >
483 >        try {
484 >            t1.start();
485 >            t2.start();
486 >            lock.readLock().lock();
487 >            lock.readLock().unlock();
488 >            Thread.sleep(SHORT_DELAY_MS);
489 >            lock.readLock().lock();
490 >            lock.readLock().unlock();
491 >            lock.writeLock().unlock();
492 >            t1.join(MEDIUM_DELAY_MS);
493 >            t2.join(MEDIUM_DELAY_MS);
494 >            assertTrue(!t1.isAlive());
495 >            assertTrue(!t2.isAlive());
496 >          
497 >        } catch(Exception e){
498 >            unexpectedException();
499 >        }
500 >    }
501 >
502 >
503 >    /**
504 >     *  Write lock succeeds if write locked by current thread even if
505 >     * other threads are waiting for writelock
506 >     */
507 >    public void testWriteHoldingWriteLock4() {
508 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
509 >        lock.writeLock().lock();
510 >        Thread t1 = new Thread(new Runnable() {
511 >                public void run() {
512 >                    lock.writeLock().lock();
513 >                    lock.writeLock().unlock();
514 >                }
515 >            });
516 >        Thread t2 = new Thread(new Runnable() {
517 >                public void run() {
518 >                    lock.writeLock().lock();
519 >                    lock.writeLock().unlock();
520 >                }
521 >            });
522 >
523 >        try {
524 >            t1.start();
525 >            t2.start();
526 >            lock.writeLock().lock();
527 >            lock.writeLock().unlock();
528 >            Thread.sleep(SHORT_DELAY_MS);
529 >            lock.writeLock().lock();
530 >            lock.writeLock().unlock();
531 >            lock.writeLock().unlock();
532 >            t1.join(MEDIUM_DELAY_MS);
533 >            t2.join(MEDIUM_DELAY_MS);
534 >            assertTrue(!t1.isAlive());
535 >            assertTrue(!t2.isAlive());
536 >          
537 >        } catch(Exception e){
538 >            unexpectedException();
539 >        }
540 >    }
541 >
542 >
543 >    /**
544 >     * Fair Read trylock succeeds if write locked by current thread
545 >     */
546 >    public void testReadHoldingWriteLockFair() {
547 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
548 >        lock.writeLock().lock();
549 >        assertTrue(lock.readLock().tryLock());
550 >        lock.readLock().unlock();
551 >        lock.writeLock().unlock();
552 >    }
553 >
554 >    /**
555 >     * Fair Read lock succeeds if write locked by current thread even if
556 >     * other threads are waiting for readlock
557 >     */
558 >    public void testReadHoldingWriteLockFair2() {
559 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
560 >        lock.writeLock().lock();
561 >        Thread t1 = new Thread(new Runnable() {
562 >                public void run() {
563                      lock.readLock().lock();
564                      lock.readLock().unlock();
565                  }
566              });
567          Thread t2 = new Thread(new Runnable() {
568 <                public void run(){
568 >                public void run() {
569                      lock.readLock().lock();
570                      lock.readLock().unlock();
571                  }
# Line 221 | Line 574 | public class ReentrantReadWriteLockTest
574          try {
575              t1.start();
576              t2.start();
577 +            lock.readLock().lock();
578 +            lock.readLock().unlock();
579              Thread.sleep(SHORT_DELAY_MS);
580 +            lock.readLock().lock();
581 +            lock.readLock().unlock();
582              lock.writeLock().unlock();
583              t1.join(MEDIUM_DELAY_MS);
584              t2.join(MEDIUM_DELAY_MS);
# Line 229 | Line 586 | public class ReentrantReadWriteLockTest
586              assertTrue(!t2.isAlive());
587            
588          } catch(Exception e){
589 <            fail("unexpected exception");
589 >            unexpectedException();
590          }
591      }
592  
593  
594 +    /**
595 +     * Fair Read lock succeeds if write locked by current thread even if
596 +     * other threads are waiting for writelock
597 +     */
598 +    public void testReadHoldingWriteLockFair3() {
599 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
600 +        lock.writeLock().lock();
601 +        Thread t1 = new Thread(new Runnable() {
602 +                public void run() {
603 +                    lock.writeLock().lock();
604 +                    lock.writeLock().unlock();
605 +                }
606 +            });
607 +        Thread t2 = new Thread(new Runnable() {
608 +                public void run() {
609 +                    lock.writeLock().lock();
610 +                    lock.writeLock().unlock();
611 +                }
612 +            });
613 +
614 +        try {
615 +            t1.start();
616 +            t2.start();
617 +            lock.readLock().lock();
618 +            lock.readLock().unlock();
619 +            Thread.sleep(SHORT_DELAY_MS);
620 +            lock.readLock().lock();
621 +            lock.readLock().unlock();
622 +            lock.writeLock().unlock();
623 +            t1.join(MEDIUM_DELAY_MS);
624 +            t2.join(MEDIUM_DELAY_MS);
625 +            assertTrue(!t1.isAlive());
626 +            assertTrue(!t2.isAlive());
627 +          
628 +        } catch(Exception e){
629 +            unexpectedException();
630 +        }
631 +    }
632 +
633 +
634 +    /**
635 +     * Fair Write lock succeeds if write locked by current thread even if
636 +     * other threads are waiting for writelock
637 +     */
638 +    public void testWriteHoldingWriteLockFair4() {
639 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
640 +        lock.writeLock().lock();
641 +        Thread t1 = new Thread(new Runnable() {
642 +                public void run() {
643 +                    lock.writeLock().lock();
644 +                    lock.writeLock().unlock();
645 +                }
646 +            });
647 +        Thread t2 = new Thread(new Runnable() {
648 +                public void run() {
649 +                    lock.writeLock().lock();
650 +                    lock.writeLock().unlock();
651 +                }
652 +            });
653 +
654 +        try {
655 +            t1.start();
656 +            t2.start();
657 +            Thread.sleep(SHORT_DELAY_MS);
658 +            assertTrue(lock.isWriteLockedByCurrentThread());
659 +            assertTrue(lock.getWriteHoldCount() == 1);
660 +            lock.writeLock().lock();
661 +            assertTrue(lock.getWriteHoldCount() == 2);
662 +            lock.writeLock().unlock();
663 +            lock.writeLock().lock();
664 +            lock.writeLock().unlock();
665 +            lock.writeLock().unlock();
666 +            t1.join(MEDIUM_DELAY_MS);
667 +            t2.join(MEDIUM_DELAY_MS);
668 +            assertTrue(!t1.isAlive());
669 +            assertTrue(!t2.isAlive());
670 +          
671 +        } catch(Exception e){
672 +            unexpectedException();
673 +        }
674 +    }
675 +
676 +
677 +    /**
678 +     * Read tryLock succeeds if readlocked but not writelocked
679 +     */
680      public void testTryLockWhenReadLocked() {
681          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
682          lock.readLock().lock();
683          Thread t = new Thread(new Runnable() {
684 <                public void run(){
684 >                public void run() {
685                      threadAssertTrue(lock.readLock().tryLock());
686                      lock.readLock().unlock();
687                  }
# Line 248 | Line 691 | public class ReentrantReadWriteLockTest
691              t.join();
692              lock.readLock().unlock();
693          } catch(Exception e){
694 <            fail("unexpected exception");
694 >            unexpectedException();
695          }
696      }
697  
698      
699  
700 +    /**
701 +     * write tryLock fails when readlocked
702 +     */
703      public void testWriteTryLockWhenReadLocked() {
704          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
705          lock.readLock().lock();
706          Thread t = new Thread(new Runnable() {
707 <                public void run(){
707 >                public void run() {
708 >                    threadAssertFalse(lock.writeLock().tryLock());
709 >                }
710 >            });
711 >        try {
712 >            t.start();
713 >            t.join();
714 >            lock.readLock().unlock();
715 >        } catch(Exception e){
716 >            unexpectedException();
717 >        }
718 >    }
719 >
720 >
721 >    /**
722 >     * Fair Read tryLock succeeds if readlocked but not writelocked
723 >     */
724 >    public void testTryLockWhenReadLockedFair() {
725 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
726 >        lock.readLock().lock();
727 >        Thread t = new Thread(new Runnable() {
728 >                public void run() {
729 >                    threadAssertTrue(lock.readLock().tryLock());
730 >                    lock.readLock().unlock();
731 >                }
732 >            });
733 >        try {
734 >            t.start();
735 >            t.join();
736 >            lock.readLock().unlock();
737 >        } catch(Exception e){
738 >            unexpectedException();
739 >        }
740 >    }
741 >
742 >    
743 >
744 >    /**
745 >     * Fair write tryLock fails when readlocked
746 >     */
747 >    public void testWriteTryLockWhenReadLockedFair() {
748 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
749 >        lock.readLock().lock();
750 >        Thread t = new Thread(new Runnable() {
751 >                public void run() {
752                      threadAssertFalse(lock.writeLock().tryLock());
753                  }
754              });
# Line 267 | Line 757 | public class ReentrantReadWriteLockTest
757              t.join();
758              lock.readLock().unlock();
759          } catch(Exception e){
760 <            fail("unexpected exception");
760 >            unexpectedException();
761          }
762      }
763  
764      
765  
766 <    public void testTryLock_Timeout(){
766 >    /**
767 >     * write timed tryLock times out if locked
768 >     */
769 >    public void testWriteTryLock_Timeout() {
770          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
771          lock.writeLock().lock();
772          Thread t = new Thread(new Runnable() {
773 <                public void run(){
773 >                public void run() {
774                      try {
775                          threadAssertFalse(lock.writeLock().tryLock(1, TimeUnit.MILLISECONDS));
776                      } catch (Exception ex) {
777 <                        threadFail("unexpected exception");
777 >                        threadUnexpectedException();
778                      }
779                  }
780              });
# Line 290 | Line 783 | public class ReentrantReadWriteLockTest
783              t.join();
784              lock.writeLock().unlock();
785          } catch(Exception e){
786 <            fail("unexpected exception");
786 >            unexpectedException();
787          }
788      }
789  
790 <    public void testTryLock_Timeout2(){
790 >    /**
791 >     * read timed tryLock times out if write-locked
792 >     */
793 >    public void testReadTryLock_Timeout() {
794          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
795          lock.writeLock().lock();
796          Thread t = new Thread(new Runnable() {
797 <                public void run(){
797 >                public void run() {
798                      try {
799                          threadAssertFalse(lock.readLock().tryLock(1, TimeUnit.MILLISECONDS));
800                      } catch (Exception ex) {
801 <                        threadFail("unexpected exception");
801 >                        threadUnexpectedException();
802                      }
803                  }
804              });
# Line 311 | Line 807 | public class ReentrantReadWriteLockTest
807              t.join();
808              lock.writeLock().unlock();
809          } catch(Exception e){
810 <            fail("unexpected exception");
810 >            unexpectedException();
811          }
812      }
813  
814  
815 <    public void testLockInterruptibly() {
815 >    /**
816 >     * write lockInterruptibly succeeds if lock free else is interruptible
817 >     */
818 >    public void testWriteLockInterruptibly() {
819          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
820          try {
821              lock.writeLock().lockInterruptibly();
822          } catch(Exception e) {
823 <            fail("unexpected exception");
823 >            unexpectedException();
824          }
825          Thread t = new Thread(new Runnable() {
826                  public void run() {
827                      try {
828                          lock.writeLock().lockInterruptibly();
829 <                        threadFail("should throw");
829 >                        threadShouldThrow();
830                      }
831                      catch(InterruptedException success) {
832                      }
# Line 339 | Line 838 | public class ReentrantReadWriteLockTest
838              t.join();
839              lock.writeLock().unlock();
840          } catch(Exception e){
841 <            fail("unexpected exception");
841 >            unexpectedException();
842          }
843      }
844  
845 <    public void testLockInterruptibly2() {
845 >    /**
846 >     *  read lockInterruptibly succeeds if lock free else is interruptible
847 >     */
848 >    public void testReadLockInterruptibly() {
849          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
850          try {
851              lock.writeLock().lockInterruptibly();
852          } catch(Exception e) {
853 <            fail("unexpected exception");
853 >            unexpectedException();
854          }
855          Thread t = new Thread(new Runnable() {
856                  public void run() {
857                      try {
858                          lock.readLock().lockInterruptibly();
859 <                        threadFail("should throw");
859 >                        threadShouldThrow();
860                      }
861                      catch(InterruptedException success) {
862                      }
# Line 366 | Line 868 | public class ReentrantReadWriteLockTest
868              t.join();
869              lock.writeLock().unlock();
870          } catch(Exception e){
871 <            fail("unexpected exception");
871 >            unexpectedException();
872          }
873      }
874  
875 +    /**
876 +     * Calling await without holding lock throws IllegalMonitorStateException
877 +     */
878      public void testAwait_IllegalMonitor() {
879          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
880          final Condition c = lock.writeLock().newCondition();
881          try {
882              c.await();
883 <            fail("should throw");
883 >            shouldThrow();
884          }
885          catch (IllegalMonitorStateException success) {
886          }
887          catch (Exception ex) {
888 <            fail("should throw IMSE");
888 >            shouldThrow();
889          }
890      }
891  
892 +    /**
893 +     * Calling signal without holding lock throws IllegalMonitorStateException
894 +     */
895      public void testSignal_IllegalMonitor() {
896          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
897          final Condition c = lock.writeLock().newCondition();
898          try {
899              c.signal();
900 <            fail("should throw");
900 >            shouldThrow();
901          }
902          catch (IllegalMonitorStateException success) {
903          }
904          catch (Exception ex) {
905 <            fail("should throw IMSE");
905 >            unexpectedException();
906          }
907      }
908  
909 +    /**
910 +     * awaitNanos without a signal times out
911 +     */
912      public void testAwaitNanos_Timeout() {
913          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
914          final Condition c = lock.writeLock().newCondition();
# Line 408 | Line 919 | public class ReentrantReadWriteLockTest
919              lock.writeLock().unlock();
920          }
921          catch (Exception ex) {
922 <            fail("unexpected exception");
922 >            unexpectedException();
923          }
924      }
925  
926 +
927 +    /**
928 +     *  timed await without a signal times out
929 +     */
930      public void testAwait_Timeout() {
931          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
932          final Condition c = lock.writeLock().newCondition();
933          try {
934              lock.writeLock().lock();
420            assertFalse(c.await(10, TimeUnit.MILLISECONDS));
935              lock.writeLock().unlock();
936          }
937          catch (Exception ex) {
938 <            fail("unexpected exception");
938 >            unexpectedException();
939          }
940      }
941  
942 +    /**
943 +     * awaitUntil without a signal times out
944 +     */
945      public void testAwaitUntil_Timeout() {
946          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
947          final Condition c = lock.writeLock().newCondition();
948          try {
949              lock.writeLock().lock();
950              java.util.Date d = new java.util.Date();
434            assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
951              lock.writeLock().unlock();
952          }
953          catch (Exception ex) {
954 <            fail("unexpected exception");
954 >            unexpectedException();
955          }
956      }
957  
958 +    /**
959 +     * await returns when signalled
960 +     */
961      public void testAwait() {
962          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
963          final Condition c = lock.writeLock().newCondition();
# Line 450 | Line 969 | public class ReentrantReadWriteLockTest
969                          lock.writeLock().unlock();
970                      }
971                      catch(InterruptedException e) {
972 <                        threadFail("unexpected exception");
972 >                        threadUnexpectedException();
973                      }
974                  }
975              });
# Line 465 | Line 984 | public class ReentrantReadWriteLockTest
984              assertFalse(t.isAlive());
985          }
986          catch (Exception ex) {
987 <            fail("unexpected exception");
987 >            unexpectedException();
988 >        }
989 >    }
990 >
991 >    /** A helper class for uninterruptible wait tests */
992 >    class UninterruptableThread extends Thread {
993 >        private Lock lock;
994 >        private Condition c;
995 >        
996 >        public volatile boolean canAwake = false;
997 >        public volatile boolean interrupted = false;
998 >        public volatile boolean lockStarted = false;
999 >        
1000 >        public UninterruptableThread(Lock lock, Condition c) {
1001 >            this.lock = lock;
1002 >            this.c = c;
1003 >        }
1004 >        
1005 >        public synchronized void run() {
1006 >            lock.lock();
1007 >            lockStarted = true;
1008 >            
1009 >            while (!canAwake) {
1010 >                c.awaitUninterruptibly();
1011 >            }
1012 >            
1013 >            interrupted = isInterrupted();
1014 >            lock.unlock();
1015          }
1016      }
1017  
1018 +    /**
1019 +     * awaitUninterruptibly doesn't abort on interrupt
1020 +     */
1021      public void testAwaitUninterruptibly() {
1022 <        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
1022 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1023          final Condition c = lock.writeLock().newCondition();
1024 <        Thread t = new Thread(new Runnable() {
476 <                public void run() {
477 <                    lock.writeLock().lock();
478 <                    c.awaitUninterruptibly();
479 <                    lock.writeLock().unlock();
480 <                }
481 <            });
1024 >        UninterruptableThread thread = new UninterruptableThread(lock.writeLock(), c);
1025  
1026          try {
1027 <            t.start();
1028 <            Thread.sleep(SHORT_DELAY_MS);
1029 <            t.interrupt();
1027 >            thread.start();
1028 >
1029 >            while (!thread.lockStarted) {
1030 >                Thread.sleep(100);
1031 >            }
1032 >
1033              lock.writeLock().lock();
1034 <            c.signal();
1035 <            lock.writeLock().unlock();
1036 <            t.join(SHORT_DELAY_MS);
1037 <            assertFalse(t.isAlive());
1038 <        }
1039 <        catch (Exception ex) {
1040 <            fail("unexpected exception");
1034 >            try {
1035 >                thread.interrupt();
1036 >                thread.canAwake = true;
1037 >                c.signal();
1038 >            } finally {
1039 >                lock.writeLock().unlock();
1040 >            }
1041 >
1042 >            thread.join();
1043 >            assertTrue(thread.interrupted);
1044 >            assertFalse(thread.isAlive());
1045 >        } catch (Exception ex) {
1046 >            unexpectedException();
1047          }
1048      }
1049  
1050 +    /**
1051 +     * await is interruptible
1052 +     */
1053      public void testAwait_Interrupt() {
1054          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
1055          final Condition c = lock.writeLock().newCondition();
# Line 504 | Line 1059 | public class ReentrantReadWriteLockTest
1059                          lock.writeLock().lock();
1060                          c.await();
1061                          lock.writeLock().unlock();
1062 <                        threadFail("should throw");
1062 >                        threadShouldThrow();
1063                      }
1064                      catch(InterruptedException success) {
1065                      }
# Line 519 | 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 +     * awaitNanos is interruptible
1083 +     */
1084      public void testAwaitNanos_Interrupt() {
1085          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
1086          final Condition c = lock.writeLock().newCondition();
# Line 532 | Line 1090 | public class ReentrantReadWriteLockTest
1090                          lock.writeLock().lock();
1091                          c.awaitNanos(SHORT_DELAY_MS * 2 * 1000000);
1092                          lock.writeLock().unlock();
1093 <                        threadFail("should throw");
1093 >                        threadShouldThrow();
1094                      }
1095                      catch(InterruptedException success) {
1096                      }
# Line 547 | Line 1105 | public class ReentrantReadWriteLockTest
1105              assertFalse(t.isAlive());
1106          }
1107          catch (Exception ex) {
1108 <            fail("unexpected exception");
1108 >            unexpectedException();
1109          }
1110      }
1111  
1112 +    /**
1113 +     * awaitUntil is interruptible
1114 +     */
1115      public void testAwaitUntil_Interrupt() {
1116          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
1117          final Condition c = lock.writeLock().newCondition();
# Line 561 | Line 1122 | public class ReentrantReadWriteLockTest
1122                          java.util.Date d = new java.util.Date();
1123                          c.awaitUntil(new java.util.Date(d.getTime() + 10000));
1124                          lock.writeLock().unlock();
1125 <                        threadFail("should throw");
1125 >                        threadShouldThrow();
1126                      }
1127                      catch(InterruptedException success) {
1128                      }
# Line 576 | Line 1137 | public class ReentrantReadWriteLockTest
1137              assertFalse(t.isAlive());
1138          }
1139          catch (Exception ex) {
1140 <            fail("unexpected exception");
1140 >            unexpectedException();
1141          }
1142      }
1143  
1144 +    /**
1145 +     * signalAll wakes up all threads
1146 +     */
1147      public void testSignalAll() {
1148          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
1149          final Condition c = lock.writeLock().newCondition();
# Line 591 | Line 1155 | public class ReentrantReadWriteLockTest
1155                          lock.writeLock().unlock();
1156                      }
1157                      catch(InterruptedException e) {
1158 <                        threadFail("unexpected exception");
1158 >                        threadUnexpectedException();
1159                      }
1160                  }
1161              });
# Line 604 | Line 1168 | public class ReentrantReadWriteLockTest
1168                          lock.writeLock().unlock();
1169                      }
1170                      catch(InterruptedException e) {
1171 <                        threadFail("unexpected exception");
1171 >                        threadUnexpectedException();
1172                      }
1173                  }
1174              });
# Line 622 | Line 1186 | public class ReentrantReadWriteLockTest
1186              assertFalse(t2.isAlive());
1187          }
1188          catch (Exception ex) {
1189 <            fail("unexpected exception");
1189 >            unexpectedException();
1190          }
1191      }
1192  
1193 +    /**
1194 +     * A serialized lock deserializes as unlocked
1195 +     */
1196      public void testSerialization() {
1197          ReentrantReadWriteLock l = new ReentrantReadWriteLock();
1198          l.readLock().lock();
# Line 644 | Line 1211 | public class ReentrantReadWriteLockTest
1211              r.readLock().unlock();
1212          } catch(Exception e){
1213              e.printStackTrace();
1214 <            fail("unexpected exception");
1214 >            unexpectedException();
1215 >        }
1216 >    }
1217 >
1218 >    /**
1219 >     * hasQueuedThreads reports whether there are waiting threads
1220 >     */
1221 >    public void testhasQueuedThreads() {
1222 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1223 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1224 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1225 >        try {
1226 >            assertFalse(lock.hasQueuedThreads());
1227 >            lock.writeLock().lock();
1228 >            t1.start();
1229 >            Thread.sleep(SHORT_DELAY_MS);
1230 >            assertTrue(lock.hasQueuedThreads());
1231 >            t2.start();
1232 >            Thread.sleep(SHORT_DELAY_MS);
1233 >            assertTrue(lock.hasQueuedThreads());
1234 >            t1.interrupt();
1235 >            Thread.sleep(SHORT_DELAY_MS);
1236 >            assertTrue(lock.hasQueuedThreads());
1237 >            lock.writeLock().unlock();
1238 >            Thread.sleep(SHORT_DELAY_MS);
1239 >            assertFalse(lock.hasQueuedThreads());
1240 >            t1.join();
1241 >            t2.join();
1242 >        } catch(Exception e){
1243 >            unexpectedException();
1244 >        }
1245 >    }
1246 >
1247 >    /**
1248 >     * hasQueuedThread(null) throws NPE
1249 >     */
1250 >    public void testHasQueuedThreadNPE() {
1251 >        final ReentrantReadWriteLock sync = new ReentrantReadWriteLock();
1252 >        try {
1253 >            sync.hasQueuedThread(null);
1254 >            shouldThrow();
1255 >        } catch (NullPointerException success) {
1256 >        }
1257 >    }
1258 >
1259 >    /**
1260 >     * hasQueuedThread reports whether a thread is queued.
1261 >     */
1262 >    public void testHasQueuedThread() {
1263 >        final ReentrantReadWriteLock sync = new ReentrantReadWriteLock();
1264 >        Thread t1 = new Thread(new InterruptedLockRunnable(sync));
1265 >        Thread t2 = new Thread(new InterruptibleLockRunnable(sync));
1266 >        try {
1267 >            assertFalse(sync.hasQueuedThread(t1));
1268 >            assertFalse(sync.hasQueuedThread(t2));
1269 >            sync.writeLock().lock();
1270 >            t1.start();
1271 >            Thread.sleep(SHORT_DELAY_MS);
1272 >            assertTrue(sync.hasQueuedThread(t1));
1273 >            t2.start();
1274 >            Thread.sleep(SHORT_DELAY_MS);
1275 >            assertTrue(sync.hasQueuedThread(t1));
1276 >            assertTrue(sync.hasQueuedThread(t2));
1277 >            t1.interrupt();
1278 >            Thread.sleep(SHORT_DELAY_MS);
1279 >            assertFalse(sync.hasQueuedThread(t1));
1280 >            assertTrue(sync.hasQueuedThread(t2));
1281 >            sync.writeLock().unlock();
1282 >            Thread.sleep(SHORT_DELAY_MS);
1283 >            assertFalse(sync.hasQueuedThread(t1));
1284 >            Thread.sleep(SHORT_DELAY_MS);
1285 >            assertFalse(sync.hasQueuedThread(t2));
1286 >            t1.join();
1287 >            t2.join();
1288 >        } catch(Exception e){
1289 >            unexpectedException();
1290 >        }
1291 >    }
1292 >
1293 >
1294 >    /**
1295 >     * getQueueLength reports number of waiting threads
1296 >     */
1297 >    public void testGetQueueLength() {
1298 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1299 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1300 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1301 >        try {
1302 >            assertEquals(0, lock.getQueueLength());
1303 >            lock.writeLock().lock();
1304 >            t1.start();
1305 >            Thread.sleep(SHORT_DELAY_MS);
1306 >            assertEquals(1, lock.getQueueLength());
1307 >            t2.start();
1308 >            Thread.sleep(SHORT_DELAY_MS);
1309 >            assertEquals(2, lock.getQueueLength());
1310 >            t1.interrupt();
1311 >            Thread.sleep(SHORT_DELAY_MS);
1312 >            assertEquals(1, lock.getQueueLength());
1313 >            lock.writeLock().unlock();
1314 >            Thread.sleep(SHORT_DELAY_MS);
1315 >            assertEquals(0, lock.getQueueLength());
1316 >            t1.join();
1317 >            t2.join();
1318 >        } catch(Exception e){
1319 >            unexpectedException();
1320 >        }
1321 >    }
1322 >
1323 >    /**
1324 >     * getQueuedThreads includes waiting threads
1325 >     */
1326 >    public void testGetQueuedThreads() {
1327 >        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
1328 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1329 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1330 >        try {
1331 >            assertTrue(lock.getQueuedThreads().isEmpty());
1332 >            lock.writeLock().lock();
1333 >            assertTrue(lock.getQueuedThreads().isEmpty());
1334 >            t1.start();
1335 >            Thread.sleep(SHORT_DELAY_MS);
1336 >            assertTrue(lock.getQueuedThreads().contains(t1));
1337 >            t2.start();
1338 >            Thread.sleep(SHORT_DELAY_MS);
1339 >            assertTrue(lock.getQueuedThreads().contains(t1));
1340 >            assertTrue(lock.getQueuedThreads().contains(t2));
1341 >            t1.interrupt();
1342 >            Thread.sleep(SHORT_DELAY_MS);
1343 >            assertFalse(lock.getQueuedThreads().contains(t1));
1344 >            assertTrue(lock.getQueuedThreads().contains(t2));
1345 >            lock.writeLock().unlock();
1346 >            Thread.sleep(SHORT_DELAY_MS);
1347 >            assertTrue(lock.getQueuedThreads().isEmpty());
1348 >            t1.join();
1349 >            t2.join();
1350 >        } catch(Exception e){
1351 >            unexpectedException();
1352 >        }
1353 >    }
1354 >
1355 >    /**
1356 >     * hasWaiters throws NPE if null
1357 >     */
1358 >    public void testHasWaitersNPE() {
1359 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1360 >        try {
1361 >            lock.hasWaiters(null);
1362 >            shouldThrow();
1363 >        } catch (NullPointerException success) {
1364 >        } catch (Exception ex) {
1365 >            unexpectedException();
1366 >        }
1367 >    }
1368 >
1369 >    /**
1370 >     * getWaitQueueLength throws NPE if null
1371 >     */
1372 >    public void testGetWaitQueueLengthNPE() {
1373 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1374 >        try {
1375 >            lock.getWaitQueueLength(null);
1376 >            shouldThrow();
1377 >        } catch (NullPointerException success) {
1378 >        } catch (Exception ex) {
1379 >            unexpectedException();
1380 >        }
1381 >    }
1382 >
1383 >
1384 >    /**
1385 >     * getWaitingThreads throws NPE if null
1386 >     */
1387 >    public void testGetWaitingThreadsNPE() {
1388 >        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
1389 >        try {
1390 >            lock.getWaitingThreads(null);
1391 >            shouldThrow();
1392 >        } catch (NullPointerException success) {
1393 >        } catch (Exception ex) {
1394 >            unexpectedException();
1395 >        }
1396 >    }
1397 >
1398 >    /**
1399 >     * hasWaiters throws IAE if not owned
1400 >     */
1401 >    public void testHasWaitersIAE() {
1402 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1403 >        final Condition c = (lock.writeLock().newCondition());
1404 >        final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock();
1405 >        try {
1406 >            lock2.hasWaiters(c);
1407 >            shouldThrow();
1408 >        } catch (IllegalArgumentException success) {
1409 >        } catch (Exception ex) {
1410 >            unexpectedException();
1411 >        }
1412 >    }
1413 >
1414 >    /**
1415 >     * hasWaiters throws IMSE if not locked
1416 >     */
1417 >    public void testHasWaitersIMSE() {
1418 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1419 >        final Condition c = (lock.writeLock().newCondition());
1420 >        try {
1421 >            lock.hasWaiters(c);
1422 >            shouldThrow();
1423 >        } catch (IllegalMonitorStateException success) {
1424 >        } catch (Exception ex) {
1425 >            unexpectedException();
1426 >        }
1427 >    }
1428 >
1429 >
1430 >    /**
1431 >     * getWaitQueueLength throws IAE if not owned
1432 >     */
1433 >    public void testGetWaitQueueLengthIAE() {
1434 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1435 >        final Condition c = (lock.writeLock().newCondition());
1436 >        final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock();
1437 >        try {
1438 >            lock2.getWaitQueueLength(c);
1439 >            shouldThrow();
1440 >        } catch (IllegalArgumentException success) {
1441 >        } catch (Exception ex) {
1442 >            unexpectedException();
1443 >        }
1444 >    }
1445 >
1446 >    /**
1447 >     * getWaitQueueLength throws IMSE if not locked
1448 >     */
1449 >    public void testGetWaitQueueLengthIMSE() {
1450 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1451 >        final Condition c = (lock.writeLock().newCondition());
1452 >        try {
1453 >            lock.getWaitQueueLength(c);
1454 >            shouldThrow();
1455 >        } catch (IllegalMonitorStateException success) {
1456 >        } catch (Exception ex) {
1457 >            unexpectedException();
1458          }
1459      }
1460  
1461  
1462 +    /**
1463 +     * getWaitingThreads throws IAE if not owned
1464 +     */
1465 +    public void testGetWaitingThreadsIAE() {
1466 +        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();  
1467 +        final Condition c = (lock.writeLock().newCondition());
1468 +        final PublicReentrantReadWriteLock lock2 = new PublicReentrantReadWriteLock();  
1469 +        try {
1470 +            lock2.getWaitingThreads(c);
1471 +            shouldThrow();
1472 +        } catch (IllegalArgumentException success) {
1473 +        } catch (Exception ex) {
1474 +            unexpectedException();
1475 +        }
1476 +    }
1477 +
1478 +    /**
1479 +     * getWaitingThreads throws IMSE if not locked
1480 +     */
1481 +    public void testGetWaitingThreadsIMSE() {
1482 +        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();  
1483 +        final Condition c = (lock.writeLock().newCondition());
1484 +        try {
1485 +            lock.getWaitingThreads(c);
1486 +            shouldThrow();
1487 +        } catch (IllegalMonitorStateException success) {
1488 +        } catch (Exception ex) {
1489 +            unexpectedException();
1490 +        }
1491 +    }
1492 +
1493 +
1494 +    /**
1495 +     * hasWaiters returns true when a thread is waiting, else false
1496 +     */
1497 +    public void testHasWaiters() {
1498 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1499 +        final Condition c = (lock.writeLock().newCondition());
1500 +        Thread t = new Thread(new Runnable() {
1501 +                public void run() {
1502 +                    try {
1503 +                        lock.writeLock().lock();
1504 +                        threadAssertFalse(lock.hasWaiters(c));
1505 +                        threadAssertEquals(0, lock.getWaitQueueLength(c));
1506 +                        c.await();
1507 +                        lock.writeLock().unlock();
1508 +                    }
1509 +                    catch(InterruptedException e) {
1510 +                        threadUnexpectedException();
1511 +                    }
1512 +                }
1513 +            });
1514 +
1515 +        try {
1516 +            t.start();
1517 +            Thread.sleep(SHORT_DELAY_MS);
1518 +            lock.writeLock().lock();
1519 +            assertTrue(lock.hasWaiters(c));
1520 +            assertEquals(1, lock.getWaitQueueLength(c));
1521 +            c.signal();
1522 +            lock.writeLock().unlock();
1523 +            Thread.sleep(SHORT_DELAY_MS);
1524 +            lock.writeLock().lock();
1525 +            assertFalse(lock.hasWaiters(c));
1526 +            assertEquals(0, lock.getWaitQueueLength(c));
1527 +            lock.writeLock().unlock();
1528 +            t.join(SHORT_DELAY_MS);
1529 +            assertFalse(t.isAlive());
1530 +        }
1531 +        catch (Exception ex) {
1532 +            unexpectedException();
1533 +        }
1534 +    }
1535 +
1536 +    /**
1537 +     * getWaitQueueLength returns number of waiting threads
1538 +     */
1539 +    public void testGetWaitQueueLength() {
1540 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1541 +        final Condition c = (lock.writeLock().newCondition());
1542 +        Thread t = new Thread(new Runnable() {
1543 +                public void run() {
1544 +                    try {
1545 +                        lock.writeLock().lock();
1546 +                        threadAssertFalse(lock.hasWaiters(c));
1547 +                        threadAssertEquals(0, lock.getWaitQueueLength(c));
1548 +                        c.await();
1549 +                        lock.writeLock().unlock();
1550 +                    }
1551 +                    catch(InterruptedException e) {
1552 +                        threadUnexpectedException();
1553 +                    }
1554 +                }
1555 +            });
1556 +
1557 +        try {
1558 +            t.start();
1559 +            Thread.sleep(SHORT_DELAY_MS);
1560 +            lock.writeLock().lock();
1561 +            assertTrue(lock.hasWaiters(c));
1562 +            assertEquals(1, lock.getWaitQueueLength(c));
1563 +            c.signal();
1564 +            lock.writeLock().unlock();
1565 +            Thread.sleep(SHORT_DELAY_MS);
1566 +            lock.writeLock().lock();
1567 +            assertFalse(lock.hasWaiters(c));
1568 +            assertEquals(0, lock.getWaitQueueLength(c));
1569 +            lock.writeLock().unlock();
1570 +            t.join(SHORT_DELAY_MS);
1571 +            assertFalse(t.isAlive());
1572 +        }
1573 +        catch (Exception ex) {
1574 +            unexpectedException();
1575 +        }
1576 +    }
1577 +
1578 +
1579 +    /**
1580 +     * getWaitingThreads returns only and all waiting threads
1581 +     */
1582 +    public void testGetWaitingThreads() {
1583 +        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();  
1584 +        final Condition c = lock.writeLock().newCondition();
1585 +        Thread t1 = new Thread(new Runnable() {
1586 +                public void run() {
1587 +                    try {
1588 +                        lock.writeLock().lock();
1589 +                        threadAssertTrue(lock.getWaitingThreads(c).isEmpty());
1590 +                        c.await();
1591 +                        lock.writeLock().unlock();
1592 +                    }
1593 +                    catch(InterruptedException e) {
1594 +                        threadUnexpectedException();
1595 +                    }
1596 +                }
1597 +            });
1598 +
1599 +        Thread t2 = new Thread(new Runnable() {
1600 +                public void run() {
1601 +                    try {
1602 +                        lock.writeLock().lock();
1603 +                        threadAssertFalse(lock.getWaitingThreads(c).isEmpty());
1604 +                        c.await();
1605 +                        lock.writeLock().unlock();
1606 +                    }
1607 +                    catch(InterruptedException e) {
1608 +                        threadUnexpectedException();
1609 +                    }
1610 +                }
1611 +            });
1612 +
1613 +        try {
1614 +            lock.writeLock().lock();
1615 +            assertTrue(lock.getWaitingThreads(c).isEmpty());
1616 +            lock.writeLock().unlock();
1617 +            t1.start();
1618 +            Thread.sleep(SHORT_DELAY_MS);
1619 +            t2.start();
1620 +            Thread.sleep(SHORT_DELAY_MS);
1621 +            lock.writeLock().lock();
1622 +            assertTrue(lock.hasWaiters(c));
1623 +            assertTrue(lock.getWaitingThreads(c).contains(t1));
1624 +            assertTrue(lock.getWaitingThreads(c).contains(t2));
1625 +            c.signalAll();
1626 +            lock.writeLock().unlock();
1627 +            Thread.sleep(SHORT_DELAY_MS);
1628 +            lock.writeLock().lock();
1629 +            assertFalse(lock.hasWaiters(c));
1630 +            assertTrue(lock.getWaitingThreads(c).isEmpty());
1631 +            lock.writeLock().unlock();
1632 +            t1.join(SHORT_DELAY_MS);
1633 +            t2.join(SHORT_DELAY_MS);
1634 +            assertFalse(t1.isAlive());
1635 +            assertFalse(t2.isAlive());
1636 +        }
1637 +        catch (Exception ex) {
1638 +            unexpectedException();
1639 +        }
1640 +    }
1641 +
1642 +    /**
1643 +     * toString indicates current lock state
1644 +     */
1645 +    public void testToString() {
1646 +        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1647 +        String us = lock.toString();
1648 +        assertTrue(us.indexOf("Write locks = 0") >= 0);
1649 +        assertTrue(us.indexOf("Read locks = 0") >= 0);
1650 +        lock.writeLock().lock();
1651 +        String ws = lock.toString();
1652 +        assertTrue(ws.indexOf("Write locks = 1") >= 0);
1653 +        assertTrue(ws.indexOf("Read locks = 0") >= 0);
1654 +        lock.writeLock().unlock();
1655 +        lock.readLock().lock();
1656 +        lock.readLock().lock();
1657 +        String rs = lock.toString();
1658 +        assertTrue(rs.indexOf("Write locks = 0") >= 0);
1659 +        assertTrue(rs.indexOf("Read locks = 2") >= 0);
1660 +    }
1661 +
1662 +    /**
1663 +     * readLock.toString indicates current lock state
1664 +     */
1665 +    public void testReadLockToString() {
1666 +        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1667 +        String us = lock.readLock().toString();
1668 +        assertTrue(us.indexOf("Read locks = 0") >= 0);
1669 +        lock.readLock().lock();
1670 +        lock.readLock().lock();
1671 +        String rs = lock.readLock().toString();
1672 +        assertTrue(rs.indexOf("Read locks = 2") >= 0);
1673 +    }
1674 +
1675 +    /**
1676 +     * writeLock.toString indicates current lock state
1677 +     */
1678 +    public void testWriteLockToString() {
1679 +        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1680 +        String us = lock.writeLock().toString();
1681 +        assertTrue(us.indexOf("Unlocked") >= 0);
1682 +        lock.writeLock().lock();
1683 +        String ls = lock.writeLock().toString();
1684 +        assertTrue(ls.indexOf("Locked") >= 0);
1685 +    }
1686 +
1687   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines