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.20 by dl, Fri Jul 2 10:24:00 2004 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 >            assertFalse(c.await(10, TimeUnit.MILLISECONDS));
695 >            lock.writeLock().unlock();
696 >        }
697 >        catch (Exception ex) {
698 >            unexpectedException();
699 >        }
700 >    }
701 >
702 >    /**
703 >     * awaitUntil without a signal times out
704 >     */
705 >    public void testAwaitUntil_Timeout() {
706 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
707 >        final Condition c = lock.writeLock().newCondition();
708 >        try {
709 >            lock.writeLock().lock();
710 >            java.util.Date d = new java.util.Date();
711 >            assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
712 >            lock.writeLock().unlock();
713 >        }
714 >        catch (Exception ex) {
715 >            unexpectedException();
716 >        }
717 >    }
718 >
719 >    /**
720 >     * await returns when signalled
721 >     */
722 >    public void testAwait() {
723 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
724 >        final Condition c = lock.writeLock().newCondition();
725          Thread t = new Thread(new Runnable() {
726                  public void run() {
727                      try {
728 <                        lock.writeLock().lockInterruptibly();
729 <                        fail("Failed to generate an Interrupted Exception");
728 >                        lock.writeLock().lock();
729 >                        c.await();
730 >                        lock.writeLock().unlock();
731                      }
732 <                    catch(InterruptedException e) {}
732 >                    catch(InterruptedException e) {
733 >                        threadUnexpectedException();
734 >                    }
735                  }
736              });
737 <        t.start();
738 <        t.interrupt();
737 >
738 >        try {
739 >            t.start();
740 >            Thread.sleep(SHORT_DELAY_MS);
741 >            lock.writeLock().lock();
742 >            c.signal();
743 >            lock.writeLock().unlock();
744 >            t.join(SHORT_DELAY_MS);
745 >            assertFalse(t.isAlive());
746 >        }
747 >        catch (Exception ex) {
748 >            unexpectedException();
749 >        }
750 >    }
751 >
752 >    /**
753 >     * awaitUninterruptibly doesn't abort on interrupt
754 >     */
755 >    public void testAwaitUninterruptibly() {
756 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
757 >        final Condition c = lock.writeLock().newCondition();
758 >        Thread t = new Thread(new Runnable() {
759 >                public void run() {
760 >                    lock.writeLock().lock();
761 >                    c.awaitUninterruptibly();
762 >                    lock.writeLock().unlock();
763 >                }
764 >            });
765 >
766 >        try {
767 >            t.start();
768 >            Thread.sleep(SHORT_DELAY_MS);
769 >            t.interrupt();
770 >            lock.writeLock().lock();
771 >            c.signal();
772 >            lock.writeLock().unlock();
773 >            assert(t.isInterrupted());
774 >            t.join(SHORT_DELAY_MS);
775 >            assertFalse(t.isAlive());
776 >        }
777 >        catch (Exception ex) {
778 >            unexpectedException();
779 >        }
780 >    }
781 >
782 >    /**
783 >     * await is interruptible
784 >     */
785 >    public void testAwait_Interrupt() {
786 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
787 >        final Condition c = lock.writeLock().newCondition();
788 >        Thread t = new Thread(new Runnable() {
789 >                public void run() {
790 >                    try {
791 >                        lock.writeLock().lock();
792 >                        c.await();
793 >                        lock.writeLock().unlock();
794 >                        threadShouldThrow();
795 >                    }
796 >                    catch(InterruptedException success) {
797 >                    }
798 >                }
799 >            });
800 >
801 >        try {
802 >            t.start();
803 >            Thread.sleep(SHORT_DELAY_MS);
804 >            t.interrupt();
805 >            t.join(SHORT_DELAY_MS);
806 >            assertFalse(t.isAlive());
807 >        }
808 >        catch (Exception ex) {
809 >            unexpectedException();
810 >        }
811 >    }
812 >
813 >    /**
814 >     * awaitNanos is interruptible
815 >     */
816 >    public void testAwaitNanos_Interrupt() {
817 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
818 >        final Condition c = lock.writeLock().newCondition();
819 >        Thread t = new Thread(new Runnable() {
820 >                public void run() {
821 >                    try {
822 >                        lock.writeLock().lock();
823 >                        c.awaitNanos(SHORT_DELAY_MS * 2 * 1000000);
824 >                        lock.writeLock().unlock();
825 >                        threadShouldThrow();
826 >                    }
827 >                    catch(InterruptedException success) {
828 >                    }
829 >                }
830 >            });
831 >
832 >        try {
833 >            t.start();
834 >            Thread.sleep(SHORT_DELAY_MS);
835 >            t.interrupt();
836 >            t.join(SHORT_DELAY_MS);
837 >            assertFalse(t.isAlive());
838 >        }
839 >        catch (Exception ex) {
840 >            unexpectedException();
841 >        }
842 >    }
843 >
844 >    /**
845 >     * awaitUntil is interruptible
846 >     */
847 >    public void testAwaitUntil_Interrupt() {
848 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
849 >        final Condition c = lock.writeLock().newCondition();
850 >        Thread t = new Thread(new Runnable() {
851 >                public void run() {
852 >                    try {
853 >                        lock.writeLock().lock();
854 >                        java.util.Date d = new java.util.Date();
855 >                        c.awaitUntil(new java.util.Date(d.getTime() + 10000));
856 >                        lock.writeLock().unlock();
857 >                        threadShouldThrow();
858 >                    }
859 >                    catch(InterruptedException success) {
860 >                    }
861 >                }
862 >            });
863 >
864 >        try {
865 >            t.start();
866 >            Thread.sleep(SHORT_DELAY_MS);
867 >            t.interrupt();
868 >            t.join(SHORT_DELAY_MS);
869 >            assertFalse(t.isAlive());
870 >        }
871 >        catch (Exception ex) {
872 >            unexpectedException();
873 >        }
874 >    }
875 >
876 >    /**
877 >     * signalAll wakes up all threads
878 >     */
879 >    public void testSignalAll() {
880 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
881 >        final Condition c = lock.writeLock().newCondition();
882 >        Thread t1 = new Thread(new Runnable() {
883 >                public void run() {
884 >                    try {
885 >                        lock.writeLock().lock();
886 >                        c.await();
887 >                        lock.writeLock().unlock();
888 >                    }
889 >                    catch(InterruptedException e) {
890 >                        threadUnexpectedException();
891 >                    }
892 >                }
893 >            });
894 >
895 >        Thread t2 = new Thread(new Runnable() {
896 >                public void run() {
897 >                    try {
898 >                        lock.writeLock().lock();
899 >                        c.await();
900 >                        lock.writeLock().unlock();
901 >                    }
902 >                    catch(InterruptedException e) {
903 >                        threadUnexpectedException();
904 >                    }
905 >                }
906 >            });
907 >
908 >        try {
909 >            t1.start();
910 >            t2.start();
911 >            Thread.sleep(SHORT_DELAY_MS);
912 >            lock.writeLock().lock();
913 >            c.signalAll();
914 >            lock.writeLock().unlock();
915 >            t1.join(SHORT_DELAY_MS);
916 >            t2.join(SHORT_DELAY_MS);
917 >            assertFalse(t1.isAlive());
918 >            assertFalse(t2.isAlive());
919 >        }
920 >        catch (Exception ex) {
921 >            unexpectedException();
922 >        }
923 >    }
924 >
925 >    /**
926 >     * A serialized lock deserializes as unlocked
927 >     */
928 >    public void testSerialization() {
929 >        ReentrantReadWriteLock l = new ReentrantReadWriteLock();
930 >        l.readLock().lock();
931 >        l.readLock().unlock();
932 >
933 >        try {
934 >            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
935 >            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
936 >            out.writeObject(l);
937 >            out.close();
938 >
939 >            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
940 >            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
941 >            ReentrantReadWriteLock r = (ReentrantReadWriteLock) in.readObject();
942 >            r.readLock().lock();
943 >            r.readLock().unlock();
944 >        } catch(Exception e){
945 >            e.printStackTrace();
946 >            unexpectedException();
947 >        }
948 >    }
949 >
950 >    /**
951 >     * hasQueuedThreads reports whether there are waiting threads
952 >     */
953 >    public void testhasQueuedThreads() {
954 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
955 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
956 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
957 >        try {
958 >            assertFalse(lock.hasQueuedThreads());
959 >            lock.writeLock().lock();
960 >            t1.start();
961 >            Thread.sleep(SHORT_DELAY_MS);
962 >            assertTrue(lock.hasQueuedThreads());
963 >            t2.start();
964 >            Thread.sleep(SHORT_DELAY_MS);
965 >            assertTrue(lock.hasQueuedThreads());
966 >            t1.interrupt();
967 >            Thread.sleep(SHORT_DELAY_MS);
968 >            assertTrue(lock.hasQueuedThreads());
969 >            lock.writeLock().unlock();
970 >            Thread.sleep(SHORT_DELAY_MS);
971 >            assertFalse(lock.hasQueuedThreads());
972 >            t1.join();
973 >            t2.join();
974 >        } catch(Exception e){
975 >            unexpectedException();
976 >        }
977 >    }
978 >
979 >    /**
980 >     * hasQueuedThread(null) throws NPE
981 >     */
982 >    public void testHasQueuedThreadNPE() {
983 >        final ReentrantReadWriteLock sync = new ReentrantReadWriteLock();
984 >        try {
985 >            sync.hasQueuedThread(null);
986 >            shouldThrow();
987 >        } catch (NullPointerException success) {
988 >        }
989 >    }
990 >
991 >    /**
992 >     * hasQueuedThread reports whether a thread is queued.
993 >     */
994 >    public void testHasQueuedThread() {
995 >        final ReentrantReadWriteLock sync = new ReentrantReadWriteLock();
996 >        Thread t1 = new Thread(new InterruptedLockRunnable(sync));
997 >        Thread t2 = new Thread(new InterruptibleLockRunnable(sync));
998 >        try {
999 >            assertFalse(sync.hasQueuedThread(t1));
1000 >            assertFalse(sync.hasQueuedThread(t2));
1001 >            sync.writeLock().lock();
1002 >            t1.start();
1003 >            Thread.sleep(SHORT_DELAY_MS);
1004 >            assertTrue(sync.hasQueuedThread(t1));
1005 >            t2.start();
1006 >            Thread.sleep(SHORT_DELAY_MS);
1007 >            assertTrue(sync.hasQueuedThread(t1));
1008 >            assertTrue(sync.hasQueuedThread(t2));
1009 >            t1.interrupt();
1010 >            Thread.sleep(SHORT_DELAY_MS);
1011 >            assertFalse(sync.hasQueuedThread(t1));
1012 >            assertTrue(sync.hasQueuedThread(t2));
1013 >            sync.writeLock().unlock();
1014 >            Thread.sleep(SHORT_DELAY_MS);
1015 >            assertFalse(sync.hasQueuedThread(t1));
1016 >            Thread.sleep(SHORT_DELAY_MS);
1017 >            assertFalse(sync.hasQueuedThread(t2));
1018 >            t1.join();
1019 >            t2.join();
1020 >        } catch(Exception e){
1021 >            unexpectedException();
1022 >        }
1023 >    }
1024 >
1025 >
1026 >    /**
1027 >     * getQueueLength reports number of waiting threads
1028 >     */
1029 >    public void testGetQueueLength() {
1030 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1031 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1032 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1033 >        try {
1034 >            assertEquals(0, lock.getQueueLength());
1035 >            lock.writeLock().lock();
1036 >            t1.start();
1037 >            Thread.sleep(SHORT_DELAY_MS);
1038 >            assertEquals(1, lock.getQueueLength());
1039 >            t2.start();
1040 >            Thread.sleep(SHORT_DELAY_MS);
1041 >            assertEquals(2, lock.getQueueLength());
1042 >            t1.interrupt();
1043 >            Thread.sleep(SHORT_DELAY_MS);
1044 >            assertEquals(1, lock.getQueueLength());
1045 >            lock.writeLock().unlock();
1046 >            Thread.sleep(SHORT_DELAY_MS);
1047 >            assertEquals(0, lock.getQueueLength());
1048 >            t1.join();
1049 >            t2.join();
1050 >        } catch(Exception e){
1051 >            unexpectedException();
1052 >        }
1053 >    }
1054 >
1055 >    /**
1056 >     * getQueuedThreads includes waiting threads
1057 >     */
1058 >    public void testGetQueuedThreads() {
1059 >        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
1060 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1061 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1062 >        try {
1063 >            assertTrue(lock.getQueuedThreads().isEmpty());
1064 >            lock.writeLock().lock();
1065 >            assertTrue(lock.getQueuedThreads().isEmpty());
1066 >            t1.start();
1067 >            Thread.sleep(SHORT_DELAY_MS);
1068 >            assertTrue(lock.getQueuedThreads().contains(t1));
1069 >            t2.start();
1070 >            Thread.sleep(SHORT_DELAY_MS);
1071 >            assertTrue(lock.getQueuedThreads().contains(t1));
1072 >            assertTrue(lock.getQueuedThreads().contains(t2));
1073 >            t1.interrupt();
1074 >            Thread.sleep(SHORT_DELAY_MS);
1075 >            assertFalse(lock.getQueuedThreads().contains(t1));
1076 >            assertTrue(lock.getQueuedThreads().contains(t2));
1077 >            lock.writeLock().unlock();
1078 >            Thread.sleep(SHORT_DELAY_MS);
1079 >            assertTrue(lock.getQueuedThreads().isEmpty());
1080 >            t1.join();
1081 >            t2.join();
1082 >        } catch(Exception e){
1083 >            unexpectedException();
1084 >        }
1085 >    }
1086 >
1087 >    /**
1088 >     * hasWaiters throws NPE if null
1089 >     */
1090 >    public void testHasWaitersNPE() {
1091 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1092 >        try {
1093 >            lock.hasWaiters(null);
1094 >            shouldThrow();
1095 >        } catch (NullPointerException success) {
1096 >        } catch (Exception ex) {
1097 >            unexpectedException();
1098 >        }
1099 >    }
1100 >
1101 >    /**
1102 >     * getWaitQueueLength throws NPE if null
1103 >     */
1104 >    public void testGetWaitQueueLengthNPE() {
1105 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1106 >        try {
1107 >            lock.getWaitQueueLength(null);
1108 >            shouldThrow();
1109 >        } catch (NullPointerException success) {
1110 >        } catch (Exception ex) {
1111 >            unexpectedException();
1112 >        }
1113 >    }
1114 >
1115 >
1116 >    /**
1117 >     * getWaitingThreads throws NPE if null
1118 >     */
1119 >    public void testGetWaitingThreadsNPE() {
1120 >        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
1121 >        try {
1122 >            lock.getWaitingThreads(null);
1123 >            shouldThrow();
1124 >        } catch (NullPointerException success) {
1125 >        } catch (Exception ex) {
1126 >            unexpectedException();
1127 >        }
1128 >    }
1129 >
1130 >    /**
1131 >     * hasWaiters throws IAE if not owned
1132 >     */
1133 >    public void testHasWaitersIAE() {
1134 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1135 >        final Condition c = (lock.writeLock().newCondition());
1136 >        final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock();
1137 >        try {
1138 >            lock2.hasWaiters(c);
1139 >            shouldThrow();
1140 >        } catch (IllegalArgumentException success) {
1141 >        } catch (Exception ex) {
1142 >            unexpectedException();
1143 >        }
1144 >    }
1145 >
1146 >    /**
1147 >     * hasWaiters throws IMSE if not locked
1148 >     */
1149 >    public void testHasWaitersIMSE() {
1150 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1151 >        final Condition c = (lock.writeLock().newCondition());
1152 >        try {
1153 >            lock.hasWaiters(c);
1154 >            shouldThrow();
1155 >        } catch (IllegalMonitorStateException success) {
1156 >        } catch (Exception ex) {
1157 >            unexpectedException();
1158 >        }
1159 >    }
1160 >
1161 >
1162 >    /**
1163 >     * getWaitQueueLength throws IAE if not owned
1164 >     */
1165 >    public void testGetWaitQueueLengthIAE() {
1166 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1167 >        final Condition c = (lock.writeLock().newCondition());
1168 >        final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock();
1169 >        try {
1170 >            lock2.getWaitQueueLength(c);
1171 >            shouldThrow();
1172 >        } catch (IllegalArgumentException success) {
1173 >        } catch (Exception ex) {
1174 >            unexpectedException();
1175 >        }
1176 >    }
1177 >
1178 >    /**
1179 >     * getWaitQueueLength throws IMSE if not locked
1180 >     */
1181 >    public void testGetWaitQueueLengthIMSE() {
1182 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1183 >        final Condition c = (lock.writeLock().newCondition());
1184 >        try {
1185 >            lock.getWaitQueueLength(c);
1186 >            shouldThrow();
1187 >        } catch (IllegalMonitorStateException success) {
1188 >        } catch (Exception ex) {
1189 >            unexpectedException();
1190 >        }
1191 >    }
1192 >
1193 >
1194 >    /**
1195 >     * getWaitingThreads throws IAE if not owned
1196 >     */
1197 >    public void testGetWaitingThreadsIAE() {
1198 >        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();  
1199 >        final Condition c = (lock.writeLock().newCondition());
1200 >        final PublicReentrantReadWriteLock lock2 = new PublicReentrantReadWriteLock();  
1201 >        try {
1202 >            lock2.getWaitingThreads(c);
1203 >            shouldThrow();
1204 >        } catch (IllegalArgumentException success) {
1205 >        } catch (Exception ex) {
1206 >            unexpectedException();
1207 >        }
1208 >    }
1209 >
1210 >    /**
1211 >     * getWaitingThreads throws IMSE if not locked
1212 >     */
1213 >    public void testGetWaitingThreadsIMSE() {
1214 >        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();  
1215 >        final Condition c = (lock.writeLock().newCondition());
1216 >        try {
1217 >            lock.getWaitingThreads(c);
1218 >            shouldThrow();
1219 >        } catch (IllegalMonitorStateException success) {
1220 >        } catch (Exception ex) {
1221 >            unexpectedException();
1222 >        }
1223 >    }
1224 >
1225 >
1226 >    /**
1227 >     * hasWaiters returns true when a thread is waiting, else false
1228 >     */
1229 >    public void testHasWaiters() {
1230 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1231 >        final Condition c = (lock.writeLock().newCondition());
1232 >        Thread t = new Thread(new Runnable() {
1233 >                public void run() {
1234 >                    try {
1235 >                        lock.writeLock().lock();
1236 >                        threadAssertFalse(lock.hasWaiters(c));
1237 >                        threadAssertEquals(0, lock.getWaitQueueLength(c));
1238 >                        c.await();
1239 >                        lock.writeLock().unlock();
1240 >                    }
1241 >                    catch(InterruptedException e) {
1242 >                        threadUnexpectedException();
1243 >                    }
1244 >                }
1245 >            });
1246 >
1247 >        try {
1248 >            t.start();
1249 >            Thread.sleep(SHORT_DELAY_MS);
1250 >            lock.writeLock().lock();
1251 >            assertTrue(lock.hasWaiters(c));
1252 >            assertEquals(1, lock.getWaitQueueLength(c));
1253 >            c.signal();
1254 >            lock.writeLock().unlock();
1255 >            Thread.sleep(SHORT_DELAY_MS);
1256 >            lock.writeLock().lock();
1257 >            assertFalse(lock.hasWaiters(c));
1258 >            assertEquals(0, lock.getWaitQueueLength(c));
1259 >            lock.writeLock().unlock();
1260 >            t.join(SHORT_DELAY_MS);
1261 >            assertFalse(t.isAlive());
1262 >        }
1263 >        catch (Exception ex) {
1264 >            unexpectedException();
1265 >        }
1266 >    }
1267 >
1268 >    /**
1269 >     * getWaitQueueLength returns number of waiting threads
1270 >     */
1271 >    public void testGetWaitQueueLength() {
1272 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1273 >        final Condition c = (lock.writeLock().newCondition());
1274 >        Thread t = new Thread(new Runnable() {
1275 >                public void run() {
1276 >                    try {
1277 >                        lock.writeLock().lock();
1278 >                        threadAssertFalse(lock.hasWaiters(c));
1279 >                        threadAssertEquals(0, lock.getWaitQueueLength(c));
1280 >                        c.await();
1281 >                        lock.writeLock().unlock();
1282 >                    }
1283 >                    catch(InterruptedException e) {
1284 >                        threadUnexpectedException();
1285 >                    }
1286 >                }
1287 >            });
1288 >
1289 >        try {
1290 >            t.start();
1291 >            Thread.sleep(SHORT_DELAY_MS);
1292 >            lock.writeLock().lock();
1293 >            assertTrue(lock.hasWaiters(c));
1294 >            assertEquals(1, lock.getWaitQueueLength(c));
1295 >            c.signal();
1296 >            lock.writeLock().unlock();
1297 >            Thread.sleep(SHORT_DELAY_MS);
1298 >            lock.writeLock().lock();
1299 >            assertFalse(lock.hasWaiters(c));
1300 >            assertEquals(0, lock.getWaitQueueLength(c));
1301 >            lock.writeLock().unlock();
1302 >            t.join(SHORT_DELAY_MS);
1303 >            assertFalse(t.isAlive());
1304 >        }
1305 >        catch (Exception ex) {
1306 >            unexpectedException();
1307 >        }
1308 >    }
1309 >
1310 >
1311 >    /**
1312 >     * getWaitingThreads returns only and all waiting threads
1313 >     */
1314 >    public void testGetWaitingThreads() {
1315 >        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();  
1316 >        final Condition c = lock.writeLock().newCondition();
1317 >        Thread t1 = new Thread(new Runnable() {
1318 >                public void run() {
1319 >                    try {
1320 >                        lock.writeLock().lock();
1321 >                        threadAssertTrue(lock.getWaitingThreads(c).isEmpty());
1322 >                        c.await();
1323 >                        lock.writeLock().unlock();
1324 >                    }
1325 >                    catch(InterruptedException e) {
1326 >                        threadUnexpectedException();
1327 >                    }
1328 >                }
1329 >            });
1330 >
1331 >        Thread t2 = new Thread(new Runnable() {
1332 >                public void run() {
1333 >                    try {
1334 >                        lock.writeLock().lock();
1335 >                        threadAssertFalse(lock.getWaitingThreads(c).isEmpty());
1336 >                        c.await();
1337 >                        lock.writeLock().unlock();
1338 >                    }
1339 >                    catch(InterruptedException e) {
1340 >                        threadUnexpectedException();
1341 >                    }
1342 >                }
1343 >            });
1344 >
1345 >        try {
1346 >            lock.writeLock().lock();
1347 >            assertTrue(lock.getWaitingThreads(c).isEmpty());
1348 >            lock.writeLock().unlock();
1349 >            t1.start();
1350 >            Thread.sleep(SHORT_DELAY_MS);
1351 >            t2.start();
1352 >            Thread.sleep(SHORT_DELAY_MS);
1353 >            lock.writeLock().lock();
1354 >            assertTrue(lock.hasWaiters(c));
1355 >            assertTrue(lock.getWaitingThreads(c).contains(t1));
1356 >            assertTrue(lock.getWaitingThreads(c).contains(t2));
1357 >            c.signalAll();
1358 >            lock.writeLock().unlock();
1359 >            Thread.sleep(SHORT_DELAY_MS);
1360 >            lock.writeLock().lock();
1361 >            assertFalse(lock.hasWaiters(c));
1362 >            assertTrue(lock.getWaitingThreads(c).isEmpty());
1363 >            lock.writeLock().unlock();
1364 >            t1.join(SHORT_DELAY_MS);
1365 >            t2.join(SHORT_DELAY_MS);
1366 >            assertFalse(t1.isAlive());
1367 >            assertFalse(t2.isAlive());
1368 >        }
1369 >        catch (Exception ex) {
1370 >            unexpectedException();
1371 >        }
1372 >    }
1373 >
1374 >    /**
1375 >     * toString indicates current lock state
1376 >     */
1377 >    public void testToString() {
1378 >        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1379 >        String us = lock.toString();
1380 >        assertTrue(us.indexOf("Write locks = 0") >= 0);
1381 >        assertTrue(us.indexOf("Read locks = 0") >= 0);
1382 >        lock.writeLock().lock();
1383 >        String ws = lock.toString();
1384 >        assertTrue(ws.indexOf("Write locks = 1") >= 0);
1385 >        assertTrue(ws.indexOf("Read locks = 0") >= 0);
1386 >        lock.writeLock().unlock();
1387 >        lock.readLock().lock();
1388 >        lock.readLock().lock();
1389 >        String rs = lock.toString();
1390 >        assertTrue(rs.indexOf("Write locks = 0") >= 0);
1391 >        assertTrue(rs.indexOf("Read locks = 2") >= 0);
1392 >    }
1393 >
1394 >    /**
1395 >     * readLock.toString indicates current lock state
1396 >     */
1397 >    public void testReadLockToString() {
1398 >        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1399 >        String us = lock.readLock().toString();
1400 >        assertTrue(us.indexOf("Read locks = 0") >= 0);
1401 >        lock.readLock().lock();
1402 >        lock.readLock().lock();
1403 >        String rs = lock.readLock().toString();
1404 >        assertTrue(rs.indexOf("Read locks = 2") >= 0);
1405 >    }
1406 >
1407 >    /**
1408 >     * writeLock.toString indicates current lock state
1409 >     */
1410 >    public void testWriteLockToString() {
1411 >        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1412 >        String us = lock.writeLock().toString();
1413 >        assertTrue(us.indexOf("Unlocked") >= 0);
1414 >        lock.writeLock().lock();
1415 >        String ls = lock.writeLock().toString();
1416 >        assertTrue(ls.indexOf("Locked") >= 0);
1417      }
112    
1418  
1419   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines