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.26 by dl, Fri Feb 24 00:03:16 2006 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines