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.24 by dl, Tue Aug 2 11:34:04 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 <    private static long SHORT_DELAY_MS = 100;
66 <    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 <     *
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 +    /**
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 <        t.start();
419 <        t.interrupt();
420 <        lock.writeLock().unlock();
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 <     * tests for interrupted exception on a timed wait
446 <     *
444 >    /**
445 >     *  Read lock succeeds if write locked by current thread even if
446 >     * other threads are waiting for writelock
447       */
448 +    public void testReadHoldingWriteLock3() {
449 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
450 +        lock.writeLock().lock();
451 +        Thread t1 = new Thread(new Runnable() {
452 +                public void run() {
453 +                    lock.writeLock().lock();
454 +                    lock.writeLock().unlock();
455 +                }
456 +            });
457 +        Thread t2 = new Thread(new Runnable() {
458 +                public void run() {
459 +                    lock.writeLock().lock();
460 +                    lock.writeLock().unlock();
461 +                }
462 +            });
463 +
464 +        try {
465 +            t1.start();
466 +            t2.start();
467 +            lock.readLock().lock();
468 +            lock.readLock().unlock();
469 +            Thread.sleep(SHORT_DELAY_MS);
470 +            lock.readLock().lock();
471 +            lock.readLock().unlock();
472 +            lock.writeLock().unlock();
473 +            t1.join(MEDIUM_DELAY_MS);
474 +            t2.join(MEDIUM_DELAY_MS);
475 +            assertTrue(!t1.isAlive());
476 +            assertTrue(!t2.isAlive());
477 +          
478 +        } catch(Exception e){
479 +            unexpectedException();
480 +        }
481 +    }
482 +
483 +
484 +    /**
485 +     *  Write lock succeeds if write locked by current thread even if
486 +     * other threads are waiting for writelock
487 +     */
488 +    public void testWriteHoldingWriteLock4() {
489 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
490 +        lock.writeLock().lock();
491 +        Thread t1 = new Thread(new Runnable() {
492 +                public void run() {
493 +                    lock.writeLock().lock();
494 +                    lock.writeLock().unlock();
495 +                }
496 +            });
497 +        Thread t2 = new Thread(new Runnable() {
498 +                public void run() {
499 +                    lock.writeLock().lock();
500 +                    lock.writeLock().unlock();
501 +                }
502 +            });
503 +
504 +        try {
505 +            t1.start();
506 +            t2.start();
507 +            lock.writeLock().lock();
508 +            lock.writeLock().unlock();
509 +            Thread.sleep(SHORT_DELAY_MS);
510 +            lock.writeLock().lock();
511 +            lock.writeLock().unlock();
512 +            lock.writeLock().unlock();
513 +            t1.join(MEDIUM_DELAY_MS);
514 +            t2.join(MEDIUM_DELAY_MS);
515 +            assertTrue(!t1.isAlive());
516 +            assertTrue(!t2.isAlive());
517 +          
518 +        } catch(Exception e){
519 +            unexpectedException();
520 +        }
521 +    }
522 +
523 +
524 +    /**
525 +     * Fair Read trylock succeeds if write locked by current thread
526 +     */
527 +    public void testReadHoldingWriteLockFair() {
528 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
529 +        lock.writeLock().lock();
530 +        assertTrue(lock.readLock().tryLock());
531 +        lock.readLock().unlock();
532 +        lock.writeLock().unlock();
533 +    }
534 +
535 +    /**
536 +     * Fair Read lock succeeds if write locked by current thread even if
537 +     * other threads are waiting for readlock
538 +     */
539 +    public void testReadHoldingWriteLockFair2() {
540 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
541 +        lock.writeLock().lock();
542 +        Thread t1 = new Thread(new Runnable() {
543 +                public void run() {
544 +                    lock.readLock().lock();
545 +                    lock.readLock().unlock();
546 +                }
547 +            });
548 +        Thread t2 = new Thread(new Runnable() {
549 +                public void run() {
550 +                    lock.readLock().lock();
551 +                    lock.readLock().unlock();
552 +                }
553 +            });
554 +
555 +        try {
556 +            t1.start();
557 +            t2.start();
558 +            lock.readLock().lock();
559 +            lock.readLock().unlock();
560 +            Thread.sleep(SHORT_DELAY_MS);
561 +            lock.readLock().lock();
562 +            lock.readLock().unlock();
563 +            lock.writeLock().unlock();
564 +            t1.join(MEDIUM_DELAY_MS);
565 +            t2.join(MEDIUM_DELAY_MS);
566 +            assertTrue(!t1.isAlive());
567 +            assertTrue(!t2.isAlive());
568 +          
569 +        } catch(Exception e){
570 +            unexpectedException();
571 +        }
572 +    }
573 +
574 +
575 +    /**
576 +     * Fair Read lock succeeds if write locked by current thread even if
577 +     * other threads are waiting for writelock
578 +     */
579 +    public void testReadHoldingWriteLockFair3() {
580 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
581 +        lock.writeLock().lock();
582 +        Thread t1 = new Thread(new Runnable() {
583 +                public void run() {
584 +                    lock.writeLock().lock();
585 +                    lock.writeLock().unlock();
586 +                }
587 +            });
588 +        Thread t2 = new Thread(new Runnable() {
589 +                public void run() {
590 +                    lock.writeLock().lock();
591 +                    lock.writeLock().unlock();
592 +                }
593 +            });
594 +
595 +        try {
596 +            t1.start();
597 +            t2.start();
598 +            lock.readLock().lock();
599 +            lock.readLock().unlock();
600 +            Thread.sleep(SHORT_DELAY_MS);
601 +            lock.readLock().lock();
602 +            lock.readLock().unlock();
603 +            lock.writeLock().unlock();
604 +            t1.join(MEDIUM_DELAY_MS);
605 +            t2.join(MEDIUM_DELAY_MS);
606 +            assertTrue(!t1.isAlive());
607 +            assertTrue(!t2.isAlive());
608 +          
609 +        } catch(Exception e){
610 +            unexpectedException();
611 +        }
612 +    }
613 +
614 +
615 +    /**
616 +     * Fair Write lock succeeds if write locked by current thread even if
617 +     * other threads are waiting for writelock
618 +     */
619 +    public void testWriteHoldingWriteLockFair4() {
620 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
621 +        lock.writeLock().lock();
622 +        Thread t1 = new Thread(new Runnable() {
623 +                public void run() {
624 +                    lock.writeLock().lock();
625 +                    lock.writeLock().unlock();
626 +                }
627 +            });
628 +        Thread t2 = new Thread(new Runnable() {
629 +                public void run() {
630 +                    lock.writeLock().lock();
631 +                    lock.writeLock().unlock();
632 +                }
633 +            });
634 +
635 +        try {
636 +            t1.start();
637 +            t2.start();
638 +            Thread.sleep(SHORT_DELAY_MS);
639 +            assertTrue(lock.isWriteLockedByCurrentThread());
640 +            assertTrue(lock.getWriteHoldCount() == 1);
641 +            lock.writeLock().lock();
642 +            assertTrue(lock.getWriteHoldCount() == 2);
643 +            lock.writeLock().unlock();
644 +            lock.writeLock().lock();
645 +            lock.writeLock().unlock();
646 +            lock.writeLock().unlock();
647 +            t1.join(MEDIUM_DELAY_MS);
648 +            t2.join(MEDIUM_DELAY_MS);
649 +            assertTrue(!t1.isAlive());
650 +            assertTrue(!t2.isAlive());
651 +          
652 +        } catch(Exception e){
653 +            unexpectedException();
654 +        }
655 +    }
656 +
657 +
658 +    /**
659 +     * Read tryLock succeeds if readlocked but not writelocked
660 +     */
661 +    public void testTryLockWhenReadLocked() {
662 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
663 +        lock.readLock().lock();
664 +        Thread t = new Thread(new Runnable() {
665 +                public void run() {
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 +     * Fair Read tryLock succeeds if readlocked but not writelocked
704 +     */
705 +    public void testTryLockWhenReadLockedFair() {
706 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
707 +        lock.readLock().lock();
708 +        Thread t = new Thread(new Runnable() {
709 +                public void run() {
710 +                    threadAssertTrue(lock.readLock().tryLock());
711 +                    lock.readLock().unlock();
712 +                }
713 +            });
714 +        try {
715 +            t.start();
716 +            t.join();
717 +            lock.readLock().unlock();
718 +        } catch(Exception e){
719 +            unexpectedException();
720 +        }
721 +    }
722 +
723 +    
724 +
725 +    /**
726 +     * Fair write tryLock fails when readlocked
727 +     */
728 +    public void testWriteTryLockWhenReadLockedFair() {
729 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
730 +        lock.readLock().lock();
731 +        Thread t = new Thread(new Runnable() {
732 +                public void run() {
733 +                    threadAssertFalse(lock.writeLock().tryLock());
734 +                }
735 +            });
736 +        try {
737 +            t.start();
738 +            t.join();
739 +            lock.readLock().unlock();
740 +        } catch(Exception e){
741 +            unexpectedException();
742 +        }
743 +    }
744 +
745      
746  
747 <    public void testInterruptedException2(){
747 >    /**
748 >     * write timed tryLock times out if locked
749 >     */
750 >    public void testWriteTryLock_Timeout() {
751          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
752          lock.writeLock().lock();
753          Thread t = new Thread(new Runnable() {
754 <                public void run(){
755 <                    try{
756 <                        lock.writeLock().tryLock(1000,TimeUnit.MILLISECONDS);
757 <                        fail("should throw");
758 <                    }catch(InterruptedException sucess){}
754 >                public void run() {
755 >                    try {
756 >                        threadAssertFalse(lock.writeLock().tryLock(1, TimeUnit.MILLISECONDS));
757 >                    } catch (Exception ex) {
758 >                        threadUnexpectedException();
759 >                    }
760                  }
761              });
762 <        t.start();
763 <        t.interrupt();
762 >        try {
763 >            t.start();
764 >            t.join();
765 >            lock.writeLock().unlock();
766 >        } catch(Exception e){
767 >            unexpectedException();
768 >        }
769 >    }
770 >
771 >    /**
772 >     * read timed tryLock times out if write-locked
773 >     */
774 >    public void testReadTryLock_Timeout() {
775 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
776 >        lock.writeLock().lock();
777 >        Thread t = new Thread(new Runnable() {
778 >                public void run() {
779 >                    try {
780 >                        threadAssertFalse(lock.readLock().tryLock(1, TimeUnit.MILLISECONDS));
781 >                    } catch (Exception ex) {
782 >                        threadUnexpectedException();
783 >                    }
784 >                }
785 >            });
786 >        try {
787 >            t.start();
788 >            t.join();
789 >            lock.writeLock().unlock();
790 >        } catch(Exception e){
791 >            unexpectedException();
792 >        }
793 >    }
794 >
795 >
796 >    /**
797 >     * write lockInterruptibly succeeds if lock free else is interruptible
798 >     */
799 >    public void testWriteLockInterruptibly() {
800 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
801 >        try {
802 >            lock.writeLock().lockInterruptibly();
803 >        } catch(Exception e) {
804 >            unexpectedException();
805 >        }
806 >        Thread t = new Thread(new Runnable() {
807 >                public void run() {
808 >                    try {
809 >                        lock.writeLock().lockInterruptibly();
810 >                        threadShouldThrow();
811 >                    }
812 >                    catch(InterruptedException success) {
813 >                    }
814 >                }
815 >            });
816 >        try {
817 >            t.start();
818 >            t.interrupt();
819 >            t.join();
820 >            lock.writeLock().unlock();
821 >        } catch(Exception e){
822 >            unexpectedException();
823 >        }
824      }
825  
826 <    
826 >    /**
827 >     *  read lockInterruptibly succeeds if lock free else is interruptible
828 >     */
829 >    public void testReadLockInterruptibly() {
830 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
831 >        try {
832 >            lock.writeLock().lockInterruptibly();
833 >        } catch(Exception e) {
834 >            unexpectedException();
835 >        }
836 >        Thread t = new Thread(new Runnable() {
837 >                public void run() {
838 >                    try {
839 >                        lock.readLock().lockInterruptibly();
840 >                        threadShouldThrow();
841 >                    }
842 >                    catch(InterruptedException success) {
843 >                    }
844 >                }
845 >            });
846 >        try {
847 >            t.start();
848 >            t.interrupt();
849 >            t.join();
850 >            lock.writeLock().unlock();
851 >        } catch(Exception e){
852 >            unexpectedException();
853 >        }
854 >    }
855  
856 <    /*
857 <     * 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
856 >    /**
857 >     * Calling await without holding lock throws IllegalMonitorStateException
858       */
859 +    public void testAwait_IllegalMonitor() {
860 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
861 +        final Condition c = lock.writeLock().newCondition();
862 +        try {
863 +            c.await();
864 +            shouldThrow();
865 +        }
866 +        catch (IllegalMonitorStateException success) {
867 +        }
868 +        catch (Exception ex) {
869 +            shouldThrow();
870 +        }
871 +    }
872  
873 <    public void testLockedInterruptibly() {
873 >    /**
874 >     * Calling signal without holding lock throws IllegalMonitorStateException
875 >     */
876 >    public void testSignal_IllegalMonitor() {
877          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
878 <        try {lock.writeLock().lockInterruptibly();} catch(Exception e) {}
878 >        final Condition c = lock.writeLock().newCondition();
879 >        try {
880 >            c.signal();
881 >            shouldThrow();
882 >        }
883 >        catch (IllegalMonitorStateException success) {
884 >        }
885 >        catch (Exception ex) {
886 >            unexpectedException();
887 >        }
888 >    }
889 >
890 >    /**
891 >     * awaitNanos without a signal times out
892 >     */
893 >    public void testAwaitNanos_Timeout() {
894 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
895 >        final Condition c = lock.writeLock().newCondition();
896 >        try {
897 >            lock.writeLock().lock();
898 >            long t = c.awaitNanos(100);
899 >            assertTrue(t <= 0);
900 >            lock.writeLock().unlock();
901 >        }
902 >        catch (Exception ex) {
903 >            unexpectedException();
904 >        }
905 >    }
906 >
907 >
908 >    /**
909 >     *  timed await without a signal times out
910 >     */
911 >    public void testAwait_Timeout() {
912 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
913 >        final Condition c = lock.writeLock().newCondition();
914 >        try {
915 >            lock.writeLock().lock();
916 >            lock.writeLock().unlock();
917 >        }
918 >        catch (Exception ex) {
919 >            unexpectedException();
920 >        }
921 >    }
922 >
923 >    /**
924 >     * awaitUntil without a signal times out
925 >     */
926 >    public void testAwaitUntil_Timeout() {
927 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
928 >        final Condition c = lock.writeLock().newCondition();
929 >        try {
930 >            lock.writeLock().lock();
931 >            java.util.Date d = new java.util.Date();
932 >            lock.writeLock().unlock();
933 >        }
934 >        catch (Exception ex) {
935 >            unexpectedException();
936 >        }
937 >    }
938 >
939 >    /**
940 >     * await returns when signalled
941 >     */
942 >    public void testAwait() {
943 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
944 >        final Condition c = lock.writeLock().newCondition();
945          Thread t = new Thread(new Runnable() {
946                  public void run() {
947                      try {
948 <                        lock.writeLock().lockInterruptibly();
949 <                        fail("Failed to generate an Interrupted Exception");
948 >                        lock.writeLock().lock();
949 >                        c.await();
950 >                        lock.writeLock().unlock();
951                      }
952 <                    catch(InterruptedException e) {}
952 >                    catch(InterruptedException e) {
953 >                        threadUnexpectedException();
954 >                    }
955                  }
956              });
957 <        t.start();
958 <        t.interrupt();
957 >
958 >        try {
959 >            t.start();
960 >            Thread.sleep(SHORT_DELAY_MS);
961 >            lock.writeLock().lock();
962 >            c.signal();
963 >            lock.writeLock().unlock();
964 >            t.join(SHORT_DELAY_MS);
965 >            assertFalse(t.isAlive());
966 >        }
967 >        catch (Exception ex) {
968 >            unexpectedException();
969 >        }
970 >    }
971 >
972 >    /** A helper class for uninterruptible wait tests */
973 >    class UninterruptableThread extends Thread {
974 >        private Lock lock;
975 >        private Condition c;
976 >        
977 >        public volatile boolean canAwake = false;
978 >        public volatile boolean interrupted = false;
979 >        public volatile boolean lockStarted = false;
980 >        
981 >        public UninterruptableThread(Lock lock, Condition c) {
982 >            this.lock = lock;
983 >            this.c = c;
984 >        }
985 >        
986 >        public synchronized void run() {
987 >            lock.lock();
988 >            lockStarted = true;
989 >            
990 >            while (!canAwake) {
991 >                c.awaitUninterruptibly();
992 >            }
993 >            
994 >            interrupted = isInterrupted();
995 >            lock.unlock();
996 >        }
997 >    }
998 >
999 >    /**
1000 >     * awaitUninterruptibly doesn't abort on interrupt
1001 >     */
1002 >    public void testAwaitUninterruptibly() {
1003 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1004 >        final Condition c = lock.writeLock().newCondition();
1005 >        UninterruptableThread thread = new UninterruptableThread(lock.writeLock(), c);
1006 >
1007 >        try {
1008 >            thread.start();
1009 >
1010 >            while (!thread.lockStarted) {
1011 >                Thread.sleep(100);
1012 >            }
1013 >
1014 >            lock.writeLock().lock();
1015 >            try {
1016 >                thread.interrupt();
1017 >                thread.canAwake = true;
1018 >                c.signal();
1019 >            } finally {
1020 >                lock.writeLock().unlock();
1021 >            }
1022 >
1023 >            thread.join();
1024 >            assertTrue(thread.interrupted);
1025 >            assertFalse(thread.isAlive());
1026 >        } catch (Exception ex) {
1027 >            unexpectedException();
1028 >        }
1029 >    }
1030 >
1031 >    /**
1032 >     * await is interruptible
1033 >     */
1034 >    public void testAwait_Interrupt() {
1035 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
1036 >        final Condition c = lock.writeLock().newCondition();
1037 >        Thread t = new Thread(new Runnable() {
1038 >                public void run() {
1039 >                    try {
1040 >                        lock.writeLock().lock();
1041 >                        c.await();
1042 >                        lock.writeLock().unlock();
1043 >                        threadShouldThrow();
1044 >                    }
1045 >                    catch(InterruptedException success) {
1046 >                    }
1047 >                }
1048 >            });
1049 >
1050 >        try {
1051 >            t.start();
1052 >            Thread.sleep(SHORT_DELAY_MS);
1053 >            t.interrupt();
1054 >            t.join(SHORT_DELAY_MS);
1055 >            assertFalse(t.isAlive());
1056 >        }
1057 >        catch (Exception ex) {
1058 >            unexpectedException();
1059 >        }
1060 >    }
1061 >
1062 >    /**
1063 >     * awaitNanos is interruptible
1064 >     */
1065 >    public void testAwaitNanos_Interrupt() {
1066 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
1067 >        final Condition c = lock.writeLock().newCondition();
1068 >        Thread t = new Thread(new Runnable() {
1069 >                public void run() {
1070 >                    try {
1071 >                        lock.writeLock().lock();
1072 >                        c.awaitNanos(SHORT_DELAY_MS * 2 * 1000000);
1073 >                        lock.writeLock().unlock();
1074 >                        threadShouldThrow();
1075 >                    }
1076 >                    catch(InterruptedException success) {
1077 >                    }
1078 >                }
1079 >            });
1080 >
1081 >        try {
1082 >            t.start();
1083 >            Thread.sleep(SHORT_DELAY_MS);
1084 >            t.interrupt();
1085 >            t.join(SHORT_DELAY_MS);
1086 >            assertFalse(t.isAlive());
1087 >        }
1088 >        catch (Exception ex) {
1089 >            unexpectedException();
1090 >        }
1091 >    }
1092 >
1093 >    /**
1094 >     * awaitUntil is interruptible
1095 >     */
1096 >    public void testAwaitUntil_Interrupt() {
1097 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
1098 >        final Condition c = lock.writeLock().newCondition();
1099 >        Thread t = new Thread(new Runnable() {
1100 >                public void run() {
1101 >                    try {
1102 >                        lock.writeLock().lock();
1103 >                        java.util.Date d = new java.util.Date();
1104 >                        c.awaitUntil(new java.util.Date(d.getTime() + 10000));
1105 >                        lock.writeLock().unlock();
1106 >                        threadShouldThrow();
1107 >                    }
1108 >                    catch(InterruptedException success) {
1109 >                    }
1110 >                }
1111 >            });
1112 >
1113 >        try {
1114 >            t.start();
1115 >            Thread.sleep(SHORT_DELAY_MS);
1116 >            t.interrupt();
1117 >            t.join(SHORT_DELAY_MS);
1118 >            assertFalse(t.isAlive());
1119 >        }
1120 >        catch (Exception ex) {
1121 >            unexpectedException();
1122 >        }
1123 >    }
1124 >
1125 >    /**
1126 >     * signalAll wakes up all threads
1127 >     */
1128 >    public void testSignalAll() {
1129 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
1130 >        final Condition c = lock.writeLock().newCondition();
1131 >        Thread t1 = new Thread(new Runnable() {
1132 >                public void run() {
1133 >                    try {
1134 >                        lock.writeLock().lock();
1135 >                        c.await();
1136 >                        lock.writeLock().unlock();
1137 >                    }
1138 >                    catch(InterruptedException e) {
1139 >                        threadUnexpectedException();
1140 >                    }
1141 >                }
1142 >            });
1143 >
1144 >        Thread t2 = new Thread(new Runnable() {
1145 >                public void run() {
1146 >                    try {
1147 >                        lock.writeLock().lock();
1148 >                        c.await();
1149 >                        lock.writeLock().unlock();
1150 >                    }
1151 >                    catch(InterruptedException e) {
1152 >                        threadUnexpectedException();
1153 >                    }
1154 >                }
1155 >            });
1156 >
1157 >        try {
1158 >            t1.start();
1159 >            t2.start();
1160 >            Thread.sleep(SHORT_DELAY_MS);
1161 >            lock.writeLock().lock();
1162 >            c.signalAll();
1163 >            lock.writeLock().unlock();
1164 >            t1.join(SHORT_DELAY_MS);
1165 >            t2.join(SHORT_DELAY_MS);
1166 >            assertFalse(t1.isAlive());
1167 >            assertFalse(t2.isAlive());
1168 >        }
1169 >        catch (Exception ex) {
1170 >            unexpectedException();
1171 >        }
1172 >    }
1173 >
1174 >    /**
1175 >     * A serialized lock deserializes as unlocked
1176 >     */
1177 >    public void testSerialization() {
1178 >        ReentrantReadWriteLock l = new ReentrantReadWriteLock();
1179 >        l.readLock().lock();
1180 >        l.readLock().unlock();
1181 >
1182 >        try {
1183 >            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
1184 >            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
1185 >            out.writeObject(l);
1186 >            out.close();
1187 >
1188 >            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
1189 >            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
1190 >            ReentrantReadWriteLock r = (ReentrantReadWriteLock) in.readObject();
1191 >            r.readLock().lock();
1192 >            r.readLock().unlock();
1193 >        } catch(Exception e){
1194 >            e.printStackTrace();
1195 >            unexpectedException();
1196 >        }
1197 >    }
1198 >
1199 >    /**
1200 >     * hasQueuedThreads reports whether there are waiting threads
1201 >     */
1202 >    public void testhasQueuedThreads() {
1203 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1204 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1205 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1206 >        try {
1207 >            assertFalse(lock.hasQueuedThreads());
1208 >            lock.writeLock().lock();
1209 >            t1.start();
1210 >            Thread.sleep(SHORT_DELAY_MS);
1211 >            assertTrue(lock.hasQueuedThreads());
1212 >            t2.start();
1213 >            Thread.sleep(SHORT_DELAY_MS);
1214 >            assertTrue(lock.hasQueuedThreads());
1215 >            t1.interrupt();
1216 >            Thread.sleep(SHORT_DELAY_MS);
1217 >            assertTrue(lock.hasQueuedThreads());
1218 >            lock.writeLock().unlock();
1219 >            Thread.sleep(SHORT_DELAY_MS);
1220 >            assertFalse(lock.hasQueuedThreads());
1221 >            t1.join();
1222 >            t2.join();
1223 >        } catch(Exception e){
1224 >            unexpectedException();
1225 >        }
1226 >    }
1227 >
1228 >    /**
1229 >     * hasQueuedThread(null) throws NPE
1230 >     */
1231 >    public void testHasQueuedThreadNPE() {
1232 >        final ReentrantReadWriteLock sync = new ReentrantReadWriteLock();
1233 >        try {
1234 >            sync.hasQueuedThread(null);
1235 >            shouldThrow();
1236 >        } catch (NullPointerException success) {
1237 >        }
1238 >    }
1239 >
1240 >    /**
1241 >     * hasQueuedThread reports whether a thread is queued.
1242 >     */
1243 >    public void testHasQueuedThread() {
1244 >        final ReentrantReadWriteLock sync = new ReentrantReadWriteLock();
1245 >        Thread t1 = new Thread(new InterruptedLockRunnable(sync));
1246 >        Thread t2 = new Thread(new InterruptibleLockRunnable(sync));
1247 >        try {
1248 >            assertFalse(sync.hasQueuedThread(t1));
1249 >            assertFalse(sync.hasQueuedThread(t2));
1250 >            sync.writeLock().lock();
1251 >            t1.start();
1252 >            Thread.sleep(SHORT_DELAY_MS);
1253 >            assertTrue(sync.hasQueuedThread(t1));
1254 >            t2.start();
1255 >            Thread.sleep(SHORT_DELAY_MS);
1256 >            assertTrue(sync.hasQueuedThread(t1));
1257 >            assertTrue(sync.hasQueuedThread(t2));
1258 >            t1.interrupt();
1259 >            Thread.sleep(SHORT_DELAY_MS);
1260 >            assertFalse(sync.hasQueuedThread(t1));
1261 >            assertTrue(sync.hasQueuedThread(t2));
1262 >            sync.writeLock().unlock();
1263 >            Thread.sleep(SHORT_DELAY_MS);
1264 >            assertFalse(sync.hasQueuedThread(t1));
1265 >            Thread.sleep(SHORT_DELAY_MS);
1266 >            assertFalse(sync.hasQueuedThread(t2));
1267 >            t1.join();
1268 >            t2.join();
1269 >        } catch(Exception e){
1270 >            unexpectedException();
1271 >        }
1272 >    }
1273 >
1274 >
1275 >    /**
1276 >     * getQueueLength reports number of waiting threads
1277 >     */
1278 >    public void testGetQueueLength() {
1279 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1280 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1281 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1282 >        try {
1283 >            assertEquals(0, lock.getQueueLength());
1284 >            lock.writeLock().lock();
1285 >            t1.start();
1286 >            Thread.sleep(SHORT_DELAY_MS);
1287 >            assertEquals(1, lock.getQueueLength());
1288 >            t2.start();
1289 >            Thread.sleep(SHORT_DELAY_MS);
1290 >            assertEquals(2, lock.getQueueLength());
1291 >            t1.interrupt();
1292 >            Thread.sleep(SHORT_DELAY_MS);
1293 >            assertEquals(1, lock.getQueueLength());
1294 >            lock.writeLock().unlock();
1295 >            Thread.sleep(SHORT_DELAY_MS);
1296 >            assertEquals(0, lock.getQueueLength());
1297 >            t1.join();
1298 >            t2.join();
1299 >        } catch(Exception e){
1300 >            unexpectedException();
1301 >        }
1302 >    }
1303 >
1304 >    /**
1305 >     * getQueuedThreads includes waiting threads
1306 >     */
1307 >    public void testGetQueuedThreads() {
1308 >        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
1309 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1310 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1311 >        try {
1312 >            assertTrue(lock.getQueuedThreads().isEmpty());
1313 >            lock.writeLock().lock();
1314 >            assertTrue(lock.getQueuedThreads().isEmpty());
1315 >            t1.start();
1316 >            Thread.sleep(SHORT_DELAY_MS);
1317 >            assertTrue(lock.getQueuedThreads().contains(t1));
1318 >            t2.start();
1319 >            Thread.sleep(SHORT_DELAY_MS);
1320 >            assertTrue(lock.getQueuedThreads().contains(t1));
1321 >            assertTrue(lock.getQueuedThreads().contains(t2));
1322 >            t1.interrupt();
1323 >            Thread.sleep(SHORT_DELAY_MS);
1324 >            assertFalse(lock.getQueuedThreads().contains(t1));
1325 >            assertTrue(lock.getQueuedThreads().contains(t2));
1326 >            lock.writeLock().unlock();
1327 >            Thread.sleep(SHORT_DELAY_MS);
1328 >            assertTrue(lock.getQueuedThreads().isEmpty());
1329 >            t1.join();
1330 >            t2.join();
1331 >        } catch(Exception e){
1332 >            unexpectedException();
1333 >        }
1334 >    }
1335 >
1336 >    /**
1337 >     * hasWaiters throws NPE if null
1338 >     */
1339 >    public void testHasWaitersNPE() {
1340 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1341 >        try {
1342 >            lock.hasWaiters(null);
1343 >            shouldThrow();
1344 >        } catch (NullPointerException success) {
1345 >        } catch (Exception ex) {
1346 >            unexpectedException();
1347 >        }
1348 >    }
1349 >
1350 >    /**
1351 >     * getWaitQueueLength throws NPE if null
1352 >     */
1353 >    public void testGetWaitQueueLengthNPE() {
1354 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1355 >        try {
1356 >            lock.getWaitQueueLength(null);
1357 >            shouldThrow();
1358 >        } catch (NullPointerException success) {
1359 >        } catch (Exception ex) {
1360 >            unexpectedException();
1361 >        }
1362 >    }
1363 >
1364 >
1365 >    /**
1366 >     * getWaitingThreads throws NPE if null
1367 >     */
1368 >    public void testGetWaitingThreadsNPE() {
1369 >        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
1370 >        try {
1371 >            lock.getWaitingThreads(null);
1372 >            shouldThrow();
1373 >        } catch (NullPointerException success) {
1374 >        } catch (Exception ex) {
1375 >            unexpectedException();
1376 >        }
1377 >    }
1378 >
1379 >    /**
1380 >     * hasWaiters throws IAE if not owned
1381 >     */
1382 >    public void testHasWaitersIAE() {
1383 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1384 >        final Condition c = (lock.writeLock().newCondition());
1385 >        final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock();
1386 >        try {
1387 >            lock2.hasWaiters(c);
1388 >            shouldThrow();
1389 >        } catch (IllegalArgumentException success) {
1390 >        } catch (Exception ex) {
1391 >            unexpectedException();
1392 >        }
1393 >    }
1394 >
1395 >    /**
1396 >     * hasWaiters throws IMSE if not locked
1397 >     */
1398 >    public void testHasWaitersIMSE() {
1399 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1400 >        final Condition c = (lock.writeLock().newCondition());
1401 >        try {
1402 >            lock.hasWaiters(c);
1403 >            shouldThrow();
1404 >        } catch (IllegalMonitorStateException success) {
1405 >        } catch (Exception ex) {
1406 >            unexpectedException();
1407 >        }
1408 >    }
1409 >
1410 >
1411 >    /**
1412 >     * getWaitQueueLength throws IAE if not owned
1413 >     */
1414 >    public void testGetWaitQueueLengthIAE() {
1415 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1416 >        final Condition c = (lock.writeLock().newCondition());
1417 >        final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock();
1418 >        try {
1419 >            lock2.getWaitQueueLength(c);
1420 >            shouldThrow();
1421 >        } catch (IllegalArgumentException success) {
1422 >        } catch (Exception ex) {
1423 >            unexpectedException();
1424 >        }
1425 >    }
1426 >
1427 >    /**
1428 >     * getWaitQueueLength throws IMSE if not locked
1429 >     */
1430 >    public void testGetWaitQueueLengthIMSE() {
1431 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1432 >        final Condition c = (lock.writeLock().newCondition());
1433 >        try {
1434 >            lock.getWaitQueueLength(c);
1435 >            shouldThrow();
1436 >        } catch (IllegalMonitorStateException success) {
1437 >        } catch (Exception ex) {
1438 >            unexpectedException();
1439 >        }
1440 >    }
1441 >
1442 >
1443 >    /**
1444 >     * getWaitingThreads throws IAE if not owned
1445 >     */
1446 >    public void testGetWaitingThreadsIAE() {
1447 >        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();  
1448 >        final Condition c = (lock.writeLock().newCondition());
1449 >        final PublicReentrantReadWriteLock lock2 = new PublicReentrantReadWriteLock();  
1450 >        try {
1451 >            lock2.getWaitingThreads(c);
1452 >            shouldThrow();
1453 >        } catch (IllegalArgumentException success) {
1454 >        } catch (Exception ex) {
1455 >            unexpectedException();
1456 >        }
1457 >    }
1458 >
1459 >    /**
1460 >     * getWaitingThreads throws IMSE if not locked
1461 >     */
1462 >    public void testGetWaitingThreadsIMSE() {
1463 >        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();  
1464 >        final Condition c = (lock.writeLock().newCondition());
1465 >        try {
1466 >            lock.getWaitingThreads(c);
1467 >            shouldThrow();
1468 >        } catch (IllegalMonitorStateException success) {
1469 >        } catch (Exception ex) {
1470 >            unexpectedException();
1471 >        }
1472 >    }
1473 >
1474 >
1475 >    /**
1476 >     * hasWaiters returns true when a thread is waiting, else false
1477 >     */
1478 >    public void testHasWaiters() {
1479 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1480 >        final Condition c = (lock.writeLock().newCondition());
1481 >        Thread t = new Thread(new Runnable() {
1482 >                public void run() {
1483 >                    try {
1484 >                        lock.writeLock().lock();
1485 >                        threadAssertFalse(lock.hasWaiters(c));
1486 >                        threadAssertEquals(0, lock.getWaitQueueLength(c));
1487 >                        c.await();
1488 >                        lock.writeLock().unlock();
1489 >                    }
1490 >                    catch(InterruptedException e) {
1491 >                        threadUnexpectedException();
1492 >                    }
1493 >                }
1494 >            });
1495 >
1496 >        try {
1497 >            t.start();
1498 >            Thread.sleep(SHORT_DELAY_MS);
1499 >            lock.writeLock().lock();
1500 >            assertTrue(lock.hasWaiters(c));
1501 >            assertEquals(1, lock.getWaitQueueLength(c));
1502 >            c.signal();
1503 >            lock.writeLock().unlock();
1504 >            Thread.sleep(SHORT_DELAY_MS);
1505 >            lock.writeLock().lock();
1506 >            assertFalse(lock.hasWaiters(c));
1507 >            assertEquals(0, lock.getWaitQueueLength(c));
1508 >            lock.writeLock().unlock();
1509 >            t.join(SHORT_DELAY_MS);
1510 >            assertFalse(t.isAlive());
1511 >        }
1512 >        catch (Exception ex) {
1513 >            unexpectedException();
1514 >        }
1515 >    }
1516 >
1517 >    /**
1518 >     * getWaitQueueLength returns number of waiting threads
1519 >     */
1520 >    public void testGetWaitQueueLength() {
1521 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1522 >        final Condition c = (lock.writeLock().newCondition());
1523 >        Thread t = new Thread(new Runnable() {
1524 >                public void run() {
1525 >                    try {
1526 >                        lock.writeLock().lock();
1527 >                        threadAssertFalse(lock.hasWaiters(c));
1528 >                        threadAssertEquals(0, lock.getWaitQueueLength(c));
1529 >                        c.await();
1530 >                        lock.writeLock().unlock();
1531 >                    }
1532 >                    catch(InterruptedException e) {
1533 >                        threadUnexpectedException();
1534 >                    }
1535 >                }
1536 >            });
1537 >
1538 >        try {
1539 >            t.start();
1540 >            Thread.sleep(SHORT_DELAY_MS);
1541 >            lock.writeLock().lock();
1542 >            assertTrue(lock.hasWaiters(c));
1543 >            assertEquals(1, lock.getWaitQueueLength(c));
1544 >            c.signal();
1545 >            lock.writeLock().unlock();
1546 >            Thread.sleep(SHORT_DELAY_MS);
1547 >            lock.writeLock().lock();
1548 >            assertFalse(lock.hasWaiters(c));
1549 >            assertEquals(0, lock.getWaitQueueLength(c));
1550 >            lock.writeLock().unlock();
1551 >            t.join(SHORT_DELAY_MS);
1552 >            assertFalse(t.isAlive());
1553 >        }
1554 >        catch (Exception ex) {
1555 >            unexpectedException();
1556 >        }
1557 >    }
1558 >
1559 >
1560 >    /**
1561 >     * getWaitingThreads returns only and all waiting threads
1562 >     */
1563 >    public void testGetWaitingThreads() {
1564 >        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();  
1565 >        final Condition c = lock.writeLock().newCondition();
1566 >        Thread t1 = new Thread(new Runnable() {
1567 >                public void run() {
1568 >                    try {
1569 >                        lock.writeLock().lock();
1570 >                        threadAssertTrue(lock.getWaitingThreads(c).isEmpty());
1571 >                        c.await();
1572 >                        lock.writeLock().unlock();
1573 >                    }
1574 >                    catch(InterruptedException e) {
1575 >                        threadUnexpectedException();
1576 >                    }
1577 >                }
1578 >            });
1579 >
1580 >        Thread t2 = new Thread(new Runnable() {
1581 >                public void run() {
1582 >                    try {
1583 >                        lock.writeLock().lock();
1584 >                        threadAssertFalse(lock.getWaitingThreads(c).isEmpty());
1585 >                        c.await();
1586 >                        lock.writeLock().unlock();
1587 >                    }
1588 >                    catch(InterruptedException e) {
1589 >                        threadUnexpectedException();
1590 >                    }
1591 >                }
1592 >            });
1593 >
1594 >        try {
1595 >            lock.writeLock().lock();
1596 >            assertTrue(lock.getWaitingThreads(c).isEmpty());
1597 >            lock.writeLock().unlock();
1598 >            t1.start();
1599 >            Thread.sleep(SHORT_DELAY_MS);
1600 >            t2.start();
1601 >            Thread.sleep(SHORT_DELAY_MS);
1602 >            lock.writeLock().lock();
1603 >            assertTrue(lock.hasWaiters(c));
1604 >            assertTrue(lock.getWaitingThreads(c).contains(t1));
1605 >            assertTrue(lock.getWaitingThreads(c).contains(t2));
1606 >            c.signalAll();
1607 >            lock.writeLock().unlock();
1608 >            Thread.sleep(SHORT_DELAY_MS);
1609 >            lock.writeLock().lock();
1610 >            assertFalse(lock.hasWaiters(c));
1611 >            assertTrue(lock.getWaitingThreads(c).isEmpty());
1612 >            lock.writeLock().unlock();
1613 >            t1.join(SHORT_DELAY_MS);
1614 >            t2.join(SHORT_DELAY_MS);
1615 >            assertFalse(t1.isAlive());
1616 >            assertFalse(t2.isAlive());
1617 >        }
1618 >        catch (Exception ex) {
1619 >            unexpectedException();
1620 >        }
1621 >    }
1622 >
1623 >    /**
1624 >     * toString indicates current lock state
1625 >     */
1626 >    public void testToString() {
1627 >        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1628 >        String us = lock.toString();
1629 >        assertTrue(us.indexOf("Write locks = 0") >= 0);
1630 >        assertTrue(us.indexOf("Read locks = 0") >= 0);
1631 >        lock.writeLock().lock();
1632 >        String ws = lock.toString();
1633 >        assertTrue(ws.indexOf("Write locks = 1") >= 0);
1634 >        assertTrue(ws.indexOf("Read locks = 0") >= 0);
1635 >        lock.writeLock().unlock();
1636 >        lock.readLock().lock();
1637 >        lock.readLock().lock();
1638 >        String rs = lock.toString();
1639 >        assertTrue(rs.indexOf("Write locks = 0") >= 0);
1640 >        assertTrue(rs.indexOf("Read locks = 2") >= 0);
1641 >    }
1642 >
1643 >    /**
1644 >     * readLock.toString indicates current lock state
1645 >     */
1646 >    public void testReadLockToString() {
1647 >        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1648 >        String us = lock.readLock().toString();
1649 >        assertTrue(us.indexOf("Read locks = 0") >= 0);
1650 >        lock.readLock().lock();
1651 >        lock.readLock().lock();
1652 >        String rs = lock.readLock().toString();
1653 >        assertTrue(rs.indexOf("Read locks = 2") >= 0);
1654 >    }
1655 >
1656 >    /**
1657 >     * writeLock.toString indicates current lock state
1658 >     */
1659 >    public void testWriteLockToString() {
1660 >        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1661 >        String us = lock.writeLock().toString();
1662 >        assertTrue(us.indexOf("Unlocked") >= 0);
1663 >        lock.writeLock().lock();
1664 >        String ls = lock.writeLock().toString();
1665 >        assertTrue(ls.indexOf("Locked") >= 0);
1666      }
112    
1667  
1668   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines