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.25 by dl, Sun Jan 29 21:17:38 2006 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines