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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines