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.22 by dl, Tue May 3 16:02:00 2005 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines