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.1 by dl, Sun Aug 31 19:24:55 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 {
13 <    static int HOLD_COUNT_TEST_LIMIT = 20;
14 <    
15 > public class ReentrantReadWriteLockTest extends JSR166TestCase {
16      public static void main(String[] args) {
17          junit.textui.TestRunner.run (suite());  
18      }
18    
19      public static Test suite() {
20          return new TestSuite(ReentrantReadWriteLockTest.class);
21      }
22  
23 +    /**
24 +     * A runnable calling lockInterruptibly
25 +     */
26 +    class InterruptibleLockRunnable implements Runnable {
27 +        final ReentrantReadWriteLock lock;
28 +        InterruptibleLockRunnable(ReentrantReadWriteLock l) { lock = l; }
29 +        public void run() {
30 +            try {
31 +                lock.writeLock().lockInterruptibly();
32 +            } catch(InterruptedException success){}
33 +        }
34 +    }
35 +
36 +
37 +    /**
38 +     * A runnable calling lockInterruptibly that expects to be
39 +     * interrupted
40 +     */
41 +    class InterruptedLockRunnable implements Runnable {
42 +        final ReentrantReadWriteLock lock;
43 +        InterruptedLockRunnable(ReentrantReadWriteLock l) { lock = l; }
44 +        public void run() {
45 +            try {
46 +                lock.writeLock().lockInterruptibly();
47 +                threadShouldThrow();
48 +            } catch(InterruptedException success){}
49 +        }
50 +    }
51 +
52 +    /**
53 +     * Subclass to expose protected methods
54 +     */
55 +    static class PublicReentrantReadWriteLock extends ReentrantReadWriteLock {
56 +        PublicReentrantReadWriteLock() { super(); }
57 +        public Collection<Thread> getQueuedThreads() {
58 +            return super.getQueuedThreads();
59 +        }
60 +        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 +        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 +    /**
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 <    private static long SHORT_DELAY_MS = 100;
142 <    private static long MEDIUM_DELAY_MS = 1000;
26 <    private static long LONG_DELAY_MS = 10000;
27 <
28 <    /*
29 <     * Unlocks an unlocked lock, throws Illegal Monitor State
30 <     *
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 <    public void testIllegalMonitorStateException(){
156 >
157 >    /**
158 >     * write-unlocking an unlocked lock throws IllegalMonitorStateException
159 >     */
160 >    public void testUnlock_IllegalMonitorStateException() {
161          ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
162 <        try{
162 >        try {
163              rl.writeLock().unlock();
164 <            fail("Should of thown Illegal Monitor State Exception");
164 >            shouldThrow();
165 >        } catch(IllegalMonitorStateException success){}
166 >    }
167  
39        }catch(IllegalMonitorStateException sucess){}
168  
169 +    /**
170 +     * write-lockInterruptibly is interruptible
171 +     */
172 +    public void testWriteLockInterruptibly_Interrupted() {
173 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
174 +        Thread t = new Thread(new Runnable() {
175 +                public void run() {
176 +                    try {
177 +                        lock.writeLock().lockInterruptibly();
178 +                        lock.writeLock().unlock();
179 +                        lock.writeLock().lockInterruptibly();
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 +            unexpectedException();
192 +        }
193 +    }
194  
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 {
204 +                        lock.writeLock().tryLock(1000,TimeUnit.MILLISECONDS);
205 +                    } catch(InterruptedException success){}
206 +                }
207 +            });
208 +        try {
209 +            t.start();
210 +            t.interrupt();
211 +            lock.writeLock().unlock();
212 +            t.join();
213 +        } catch(Exception e){
214 +            unexpectedException();
215 +        }
216      }
217 +
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 {
227 +                        lock.readLock().lockInterruptibly();
228 +                    } catch(InterruptedException success){}
229 +                }
230 +            });
231 +        try {
232 +            t.start();
233 +            t.interrupt();
234 +            lock.writeLock().unlock();
235 +            t.join();
236 +        } catch(Exception e){
237 +            unexpectedException();
238 +        }
239 +    }
240 +
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 {
250 +                        lock.readLock().tryLock(1000,TimeUnit.MILLISECONDS);
251 +                        threadShouldThrow();
252 +                    } catch(InterruptedException success){}
253 +                }
254 +            });
255 +        try {
256 +            t.start();
257 +            t.interrupt();
258 +            t.join();
259 +        } catch(Exception e){
260 +            unexpectedException();
261 +        }
262 +    }
263 +
264      
265 <    /*
266 <     * makes a lock, locks it, tries to aquire the lock in another thread
46 <     * interrupts that thread and waits for an interrupted Exception to
47 <     * be thrown.
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 +                    threadAssertFalse(lock.writeLock().tryLock());
274 +                }
275 +            });
276 +        try {
277 +            t.start();
278 +            t.join();
279 +            lock.writeLock().unlock();
280 +        } catch(Exception e){
281 +            unexpectedException();
282 +        }
283 +    }
284  
285 <    public void testInterruptedException(){
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 <                    try{
294 <                        lock.writeLock().lockInterruptibly();
295 <                        fail("should throw");
296 <                    }catch(InterruptedException sucess){}
292 >                public void run() {
293 >                    threadAssertFalse(lock.readLock().tryLock());
294 >                }
295 >            });
296 >        try {
297 >            t.start();
298 >            t.join();
299 >            lock.writeLock().unlock();
300 >        } catch(Exception e){
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 >                    threadAssertTrue(lock.readLock().tryLock());
314 >                    lock.readLock().unlock();
315 >                }
316 >            });
317 >        try {
318 >            t.start();
319 >            t.join();
320 >            lock.readLock().unlock();
321 >        } catch(Exception e){
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() {
334 >                    lock.readLock().lock();
335 >                    lock.readLock().unlock();
336 >                }
337 >            });
338 >        Thread t2 = new Thread(new Runnable() {
339 >                public void run() {
340 >                    lock.writeLock().lock();
341 >                    lock.writeLock().unlock();
342 >                }
343 >            });
344 >
345 >        try {
346 >            t1.start();
347 >            t2.start();
348 >            Thread.sleep(SHORT_DELAY_MS);
349 >            lock.readLock().unlock();
350 >            t1.join(MEDIUM_DELAY_MS);
351 >            t2.join(MEDIUM_DELAY_MS);
352 >            assertTrue(!t1.isAlive());
353 >            assertTrue(!t2.isAlive());
354 >          
355 >        } catch(Exception e){
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() {
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 <        t.start();
458 <        t.interrupt();
459 <        lock.writeLock().unlock();
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 <     * tests for interrupted exception on a timed wait
485 <     *
483 >
484 >    /**
485 >     *  Write lock succeeds if write locked by current thread even if
486 >     * other threads are waiting for writelock
487       */
488 +    public void testWriteHoldingWriteLock4() {
489 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
490 +        lock.writeLock().lock();
491 +        Thread t1 = new Thread(new Runnable() {
492 +                public void run() {
493 +                    lock.writeLock().lock();
494 +                    lock.writeLock().unlock();
495 +                }
496 +            });
497 +        Thread t2 = new Thread(new Runnable() {
498 +                public void run() {
499 +                    lock.writeLock().lock();
500 +                    lock.writeLock().unlock();
501 +                }
502 +            });
503 +
504 +        try {
505 +            t1.start();
506 +            t2.start();
507 +            lock.writeLock().lock();
508 +            lock.writeLock().unlock();
509 +            Thread.sleep(SHORT_DELAY_MS);
510 +            lock.writeLock().lock();
511 +            lock.writeLock().unlock();
512 +            lock.writeLock().unlock();
513 +            t1.join(MEDIUM_DELAY_MS);
514 +            t2.join(MEDIUM_DELAY_MS);
515 +            assertTrue(!t1.isAlive());
516 +            assertTrue(!t2.isAlive());
517 +          
518 +        } catch(Exception e){
519 +            unexpectedException();
520 +        }
521 +    }
522 +
523 +
524 +    /**
525 +     * Fair Read trylock succeeds if write locked by current thread
526 +     */
527 +    public void testReadHoldingWriteLockFair() {
528 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
529 +        lock.writeLock().lock();
530 +        assertTrue(lock.readLock().tryLock());
531 +        lock.readLock().unlock();
532 +        lock.writeLock().unlock();
533 +    }
534 +
535 +    /**
536 +     * Fair Read lock succeeds if write locked by current thread even if
537 +     * other threads are waiting for readlock
538 +     */
539 +    public void testReadHoldingWriteLockFair2() {
540 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
541 +        lock.writeLock().lock();
542 +        Thread t1 = new Thread(new Runnable() {
543 +                public void run() {
544 +                    lock.readLock().lock();
545 +                    lock.readLock().unlock();
546 +                }
547 +            });
548 +        Thread t2 = new Thread(new Runnable() {
549 +                public void run() {
550 +                    lock.readLock().lock();
551 +                    lock.readLock().unlock();
552 +                }
553 +            });
554 +
555 +        try {
556 +            t1.start();
557 +            t2.start();
558 +            lock.readLock().lock();
559 +            lock.readLock().unlock();
560 +            Thread.sleep(SHORT_DELAY_MS);
561 +            lock.readLock().lock();
562 +            lock.readLock().unlock();
563 +            lock.writeLock().unlock();
564 +            t1.join(MEDIUM_DELAY_MS);
565 +            t2.join(MEDIUM_DELAY_MS);
566 +            assertTrue(!t1.isAlive());
567 +            assertTrue(!t2.isAlive());
568 +          
569 +        } catch(Exception e){
570 +            unexpectedException();
571 +        }
572 +    }
573 +
574 +
575 +    /**
576 +     * Fair Read lock succeeds if write locked by current thread even if
577 +     * other threads are waiting for writelock
578 +     */
579 +    public void testReadHoldingWriteLockFair3() {
580 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
581 +        lock.writeLock().lock();
582 +        Thread t1 = new Thread(new Runnable() {
583 +                public void run() {
584 +                    lock.writeLock().lock();
585 +                    lock.writeLock().unlock();
586 +                }
587 +            });
588 +        Thread t2 = new Thread(new Runnable() {
589 +                public void run() {
590 +                    lock.writeLock().lock();
591 +                    lock.writeLock().unlock();
592 +                }
593 +            });
594 +
595 +        try {
596 +            t1.start();
597 +            t2.start();
598 +            lock.readLock().lock();
599 +            lock.readLock().unlock();
600 +            Thread.sleep(SHORT_DELAY_MS);
601 +            lock.readLock().lock();
602 +            lock.readLock().unlock();
603 +            lock.writeLock().unlock();
604 +            t1.join(MEDIUM_DELAY_MS);
605 +            t2.join(MEDIUM_DELAY_MS);
606 +            assertTrue(!t1.isAlive());
607 +            assertTrue(!t2.isAlive());
608 +          
609 +        } catch(Exception e){
610 +            unexpectedException();
611 +        }
612 +    }
613 +
614 +
615 +    /**
616 +     * Fair Write lock succeeds if write locked by current thread even if
617 +     * other threads are waiting for writelock
618 +     */
619 +    public void testWriteHoldingWriteLockFair4() {
620 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
621 +        lock.writeLock().lock();
622 +        Thread t1 = new Thread(new Runnable() {
623 +                public void run() {
624 +                    lock.writeLock().lock();
625 +                    lock.writeLock().unlock();
626 +                }
627 +            });
628 +        Thread t2 = new Thread(new Runnable() {
629 +                public void run() {
630 +                    lock.writeLock().lock();
631 +                    lock.writeLock().unlock();
632 +                }
633 +            });
634 +
635 +        try {
636 +            t1.start();
637 +            t2.start();
638 +            Thread.sleep(SHORT_DELAY_MS);
639 +            assertTrue(lock.isWriteLockedByCurrentThread());
640 +            assertTrue(lock.getWriteHoldCount() == 1);
641 +            lock.writeLock().lock();
642 +            assertTrue(lock.getWriteHoldCount() == 2);
643 +            lock.writeLock().unlock();
644 +            lock.writeLock().lock();
645 +            lock.writeLock().unlock();
646 +            lock.writeLock().unlock();
647 +            t1.join(MEDIUM_DELAY_MS);
648 +            t2.join(MEDIUM_DELAY_MS);
649 +            assertTrue(!t1.isAlive());
650 +            assertTrue(!t2.isAlive());
651 +          
652 +        } catch(Exception e){
653 +            unexpectedException();
654 +        }
655 +    }
656 +
657 +
658 +    /**
659 +     * Read tryLock succeeds if readlocked but not writelocked
660 +     */
661 +    public void testTryLockWhenReadLocked() {
662 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
663 +        lock.readLock().lock();
664 +        Thread t = new Thread(new Runnable() {
665 +                public void run() {
666 +                    threadAssertTrue(lock.readLock().tryLock());
667 +                    lock.readLock().unlock();
668 +                }
669 +            });
670 +        try {
671 +            t.start();
672 +            t.join();
673 +            lock.readLock().unlock();
674 +        } catch(Exception e){
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 +                    threadAssertFalse(lock.writeLock().tryLock());
690 +                }
691 +            });
692 +        try {
693 +            t.start();
694 +            t.join();
695 +            lock.readLock().unlock();
696 +        } catch(Exception e){
697 +            unexpectedException();
698 +        }
699 +    }
700 +
701      
702  
703 <    public void testInterruptedException2(){
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(){
711 <                    try{
712 <                        lock.writeLock().tryLock(1000,TimeUnit.MILLISECONDS);
713 <                        fail("should throw");
714 <                    }catch(InterruptedException sucess){}
710 >                public void run() {
711 >                    try {
712 >                        threadAssertFalse(lock.writeLock().tryLock(1, TimeUnit.MILLISECONDS));
713 >                    } catch (Exception ex) {
714 >                        threadUnexpectedException();
715 >                    }
716 >                }
717 >            });
718 >        try {
719 >            t.start();
720 >            t.join();
721 >            lock.writeLock().unlock();
722 >        } catch(Exception e){
723 >            unexpectedException();
724 >        }
725 >    }
726 >
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() {
735 >                    try {
736 >                        threadAssertFalse(lock.readLock().tryLock(1, TimeUnit.MILLISECONDS));
737 >                    } catch (Exception ex) {
738 >                        threadUnexpectedException();
739 >                    }
740 >                }
741 >            });
742 >        try {
743 >            t.start();
744 >            t.join();
745 >            lock.writeLock().unlock();
746 >        } catch(Exception e){
747 >            unexpectedException();
748 >        }
749 >    }
750 >
751 >
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 >            unexpectedException();
761 >        }
762 >        Thread t = new Thread(new Runnable() {
763 >                public void run() {
764 >                    try {
765 >                        lock.writeLock().lockInterruptibly();
766 >                        threadShouldThrow();
767 >                    }
768 >                    catch(InterruptedException success) {
769 >                    }
770                  }
771              });
772 <        t.start();
773 <        t.interrupt();
772 >        try {
773 >            t.start();
774 >            t.interrupt();
775 >            t.join();
776 >            lock.writeLock().unlock();
777 >        } catch(Exception e){
778 >            unexpectedException();
779 >        }
780      }
781  
782 <    
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 >            unexpectedException();
791 >        }
792 >        Thread t = new Thread(new Runnable() {
793 >                public void run() {
794 >                    try {
795 >                        lock.readLock().lockInterruptibly();
796 >                        threadShouldThrow();
797 >                    }
798 >                    catch(InterruptedException success) {
799 >                    }
800 >                }
801 >            });
802 >        try {
803 >            t.start();
804 >            t.interrupt();
805 >            t.join();
806 >            lock.writeLock().unlock();
807 >        } catch(Exception e){
808 >            unexpectedException();
809 >        }
810 >    }
811  
812 <    /*
813 <     * current thread locks interruptibly the thread
91 <     * another thread tries to aquire the lock and blocks
92 <     * on the call. interrupt the attempted aquireLock
93 <     * assert that the first lock() call actually locked the lock
94 <     * assert that the current thread is the one holding the lock
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 +            shouldThrow();
821 +        }
822 +        catch (IllegalMonitorStateException success) {
823 +        }
824 +        catch (Exception ex) {
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 +            shouldThrow();
838 +        }
839 +        catch (IllegalMonitorStateException success) {
840 +        }
841 +        catch (Exception ex) {
842 +            unexpectedException();
843 +        }
844 +    }
845  
846 <    public void testLockedInterruptibly() {
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();
852 >        try {
853 >            lock.writeLock().lock();
854 >            long t = c.awaitNanos(100);
855 >            assertTrue(t <= 0);
856 >            lock.writeLock().unlock();
857 >        }
858 >        catch (Exception ex) {
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 <        try {lock.writeLock().lockInterruptibly();} catch(Exception e) {}
869 >        final Condition c = lock.writeLock().newCondition();
870 >        try {
871 >            lock.writeLock().lock();
872 >            lock.writeLock().unlock();
873 >        }
874 >        catch (Exception ex) {
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();
888 >            lock.writeLock().unlock();
889 >        }
890 >        catch (Exception ex) {
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();
901          Thread t = new Thread(new Runnable() {
902                  public void run() {
903                      try {
904 <                        lock.writeLock().lockInterruptibly();
905 <                        fail("Failed to generate an Interrupted Exception");
904 >                        lock.writeLock().lock();
905 >                        c.await();
906 >                        lock.writeLock().unlock();
907                      }
908 <                    catch(InterruptedException e) {}
908 >                    catch(InterruptedException e) {
909 >                        threadUnexpectedException();
910 >                    }
911                  }
912              });
913 <        t.start();
914 <        t.interrupt();
913 >
914 >        try {
915 >            t.start();
916 >            Thread.sleep(SHORT_DELAY_MS);
917 >            lock.writeLock().lock();
918 >            c.signal();
919 >            lock.writeLock().unlock();
920 >            t.join(SHORT_DELAY_MS);
921 >            assertFalse(t.isAlive());
922 >        }
923 >        catch (Exception ex) {
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();
960 >        final Condition c = lock.writeLock().newCondition();
961 >        UninterruptableThread thread = new UninterruptableThread(lock.writeLock(), c);
962 >
963 >        try {
964 >            thread.start();
965 >
966 >            while (!thread.lockStarted) {
967 >                Thread.sleep(100);
968 >            }
969 >
970 >            lock.writeLock().lock();
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();
993 >        Thread t = new Thread(new Runnable() {
994 >                public void run() {
995 >                    try {
996 >                        lock.writeLock().lock();
997 >                        c.await();
998 >                        lock.writeLock().unlock();
999 >                        threadShouldThrow();
1000 >                    }
1001 >                    catch(InterruptedException success) {
1002 >                    }
1003 >                }
1004 >            });
1005 >
1006 >        try {
1007 >            t.start();
1008 >            Thread.sleep(SHORT_DELAY_MS);
1009 >            t.interrupt();
1010 >            t.join(SHORT_DELAY_MS);
1011 >            assertFalse(t.isAlive());
1012 >        }
1013 >        catch (Exception ex) {
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();
1024 >        Thread t = new Thread(new Runnable() {
1025 >                public void run() {
1026 >                    try {
1027 >                        lock.writeLock().lock();
1028 >                        c.awaitNanos(SHORT_DELAY_MS * 2 * 1000000);
1029 >                        lock.writeLock().unlock();
1030 >                        threadShouldThrow();
1031 >                    }
1032 >                    catch(InterruptedException success) {
1033 >                    }
1034 >                }
1035 >            });
1036 >
1037 >        try {
1038 >            t.start();
1039 >            Thread.sleep(SHORT_DELAY_MS);
1040 >            t.interrupt();
1041 >            t.join(SHORT_DELAY_MS);
1042 >            assertFalse(t.isAlive());
1043 >        }
1044 >        catch (Exception ex) {
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();
1055 >        Thread t = new Thread(new Runnable() {
1056 >                public void run() {
1057 >                    try {
1058 >                        lock.writeLock().lock();
1059 >                        java.util.Date d = new java.util.Date();
1060 >                        c.awaitUntil(new java.util.Date(d.getTime() + 10000));
1061 >                        lock.writeLock().unlock();
1062 >                        threadShouldThrow();
1063 >                    }
1064 >                    catch(InterruptedException success) {
1065 >                    }
1066 >                }
1067 >            });
1068 >
1069 >        try {
1070 >            t.start();
1071 >            Thread.sleep(SHORT_DELAY_MS);
1072 >            t.interrupt();
1073 >            t.join(SHORT_DELAY_MS);
1074 >            assertFalse(t.isAlive());
1075 >        }
1076 >        catch (Exception ex) {
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();
1087 >        Thread t1 = new Thread(new Runnable() {
1088 >                public void run() {
1089 >                    try {
1090 >                        lock.writeLock().lock();
1091 >                        c.await();
1092 >                        lock.writeLock().unlock();
1093 >                    }
1094 >                    catch(InterruptedException e) {
1095 >                        threadUnexpectedException();
1096 >                    }
1097 >                }
1098 >            });
1099 >
1100 >        Thread t2 = new Thread(new Runnable() {
1101 >                public void run() {
1102 >                    try {
1103 >                        lock.writeLock().lock();
1104 >                        c.await();
1105 >                        lock.writeLock().unlock();
1106 >                    }
1107 >                    catch(InterruptedException e) {
1108 >                        threadUnexpectedException();
1109 >                    }
1110 >                }
1111 >            });
1112 >
1113 >        try {
1114 >            t1.start();
1115 >            t2.start();
1116 >            Thread.sleep(SHORT_DELAY_MS);
1117 >            lock.writeLock().lock();
1118 >            c.signalAll();
1119 >            lock.writeLock().unlock();
1120 >            t1.join(SHORT_DELAY_MS);
1121 >            t2.join(SHORT_DELAY_MS);
1122 >            assertFalse(t1.isAlive());
1123 >            assertFalse(t2.isAlive());
1124 >        }
1125 >        catch (Exception ex) {
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();
1136 >        l.readLock().unlock();
1137 >
1138 >        try {
1139 >            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
1140 >            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
1141 >            out.writeObject(l);
1142 >            out.close();
1143 >
1144 >            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
1145 >            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
1146 >            ReentrantReadWriteLock r = (ReentrantReadWriteLock) in.readObject();
1147 >            r.readLock().lock();
1148 >            r.readLock().unlock();
1149 >        } catch(Exception e){
1150 >            e.printStackTrace();
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      }
112    
1623  
1624   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines