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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines