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.2 by dl, Sun Sep 7 20:39:11 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 {
14 <    static int HOLD_COUNT_TEST_LIMIT = 20;
15 <    
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      }
19    
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 <    private static long SHORT_DELAY_MS = 100;
61 <    private static long MEDIUM_DELAY_MS = 1000;
27 <    private static long LONG_DELAY_MS = 10000;
28 <
29 <    /*
30 <     * Unlocks an unlocked lock, throws Illegal Monitor State
31 <     *
60 >    /**
61 >     * Constructor sets given fairness, and is in unlocked state
62       */
63 <    
34 <    public void testIllegalMonitorStateException(){
63 >    public void testConstructor() {
64          ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
65 <        try{
66 <            rl.writeLock().unlock();
67 <            fail("Should of thown Illegal Monitor State Exception");
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 <        }catch(IllegalMonitorStateException success){}
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  
175 +    /**
176 +     * write-unlocking an unlocked lock throws IllegalMonitorStateException
177 +     */
178 +    public void testUnlock_IllegalMonitorStateException() {
179 +        ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
180 +        try {
181 +            rl.writeLock().unlock();
182 +            shouldThrow();
183 +        } catch (IllegalMonitorStateException success) {}
184 +    }
185 +
186  
187 <    public void testInterruptedException(){
187 >    /**
188 >     * write-lockInterruptibly is interruptible
189 >     */
190 >    public void testWriteLockInterruptibly_Interrupted() throws Exception {
191          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
47        lock.writeLock().lock();
192          Thread t = new Thread(new Runnable() {
193 <                public void run(){
194 <                    try{
193 >                public void run() {
194 >                    try {
195 >                        lock.writeLock().lockInterruptibly();
196 >                        lock.writeLock().unlock();
197                          lock.writeLock().lockInterruptibly();
198 <                        fail("should throw");
199 <                    }catch(InterruptedException success){}
198 >                        lock.writeLock().unlock();
199 >                    } catch (InterruptedException success) {}
200                  }
201              });
56        try {
57            t.start();
58            t.interrupt();
59            lock.writeLock().unlock();
60            t.join();
61        } catch(Exception e){
62            fail("unexpected exception");
63        }
64    }
202  
203 <    public void testInterruptedException2(){
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 >     * 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{
219 >                public void run() {
220 >                    try {
221                          lock.writeLock().tryLock(1000,TimeUnit.MILLISECONDS);
222 <                        fail("should throw");
74 <                    }catch(InterruptedException success){}
222 >                    } catch (InterruptedException success) {}
223                  }
224              });
225 <        try {
226 <            t.start();
227 <            t.interrupt();
228 <            lock.writeLock().unlock();
229 <            t.join();
82 <        } catch(Exception e){
83 <            fail("unexpected exception");
84 <        }
225 >
226 >        t.start();
227 >        t.interrupt();
228 >        lock.writeLock().unlock();
229 >        t.join();
230      }
231  
232 <    public void testInterruptedException3(){
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{
239 >                public void run() {
240 >                    try {
241                          lock.readLock().lockInterruptibly();
242 <                        fail("should throw");
95 <                    }catch(InterruptedException success){}
242 >                    } catch (InterruptedException success) {}
243                  }
244              });
98        try {
99            t.start();
100            t.interrupt();
101            lock.writeLock().unlock();
102            t.join();
103        } catch(Exception e){
104            fail("unexpected exception");
105        }
106    }
245  
246 <    public void testInterruptedException4(){
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 >    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{
261 >                public void run() {
262 >                    try {
263                          lock.readLock().tryLock(1000,TimeUnit.MILLISECONDS);
264 <                        fail("should throw");
265 <                    }catch(InterruptedException success){}
264 >                        threadShouldThrow();
265 >                    } catch (InterruptedException success) {}
266                  }
267              });
268 <        try {
269 <            t.start();
270 <            t.interrupt();
271 <            t.join();
123 <        } catch(Exception e){
124 <            fail("unexpected exception");
125 <        }
268 >
269 >        t.start();
270 >        t.interrupt();
271 >        t.join();
272      }
273  
274 <    
275 <    public void testTryLockWhenLocked() {
274 >
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 <                    assertFalse(lock.writeLock().tryLock());
282 >                public void run() {
283 >                    threadAssertFalse(lock.writeLock().tryLock());
284                  }
285              });
137        try {
138            t.start();
139            t.join();
140            lock.writeLock().unlock();
141        } catch(Exception e){
142            fail("unexpected exception");
143        }
144    }
286  
287 <    public void testTryLockWhenLocked2() {
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 <                    assertFalse(lock.readLock().tryLock());
299 >                public void run() {
300 >                    threadAssertFalse(lock.readLock().tryLock());
301                  }
302              });
154        try {
155            t.start();
156            t.join();
157            lock.writeLock().unlock();
158        } catch(Exception e){
159            fail("unexpected exception");
160        }
161    }
303  
304 <    public void testMultipleReadLocks() {
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 <                    assertTrue(lock.readLock().tryLock());
316 >                public void run() {
317 >                    threadAssertTrue(lock.readLock().tryLock());
318                      lock.readLock().unlock();
319                  }
320              });
172        try {
173            t.start();
174            t.join();
175            lock.readLock().unlock();
176        } catch(Exception e){
177            fail("unexpected exception");
178        }
179    }
321  
322 <    public void testWriteAfterMultipleReadLocks() {
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(){
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(){
340 >                public void run() {
341                      lock.writeLock().lock();
342                      lock.writeLock().unlock();
343                  }
344              });
345  
346 <        try {
347 <            t1.start();
348 <            t2.start();
349 <            Thread.sleep(SHORT_DELAY_MS);
350 <            lock.readLock().unlock();
351 <            t1.join(MEDIUM_DELAY_MS);
352 <            t2.join(MEDIUM_DELAY_MS);
353 <            assertTrue(!t1.isAlive());
354 <            assertTrue(!t2.isAlive());
206 <          
207 <        } catch(Exception e){
208 <            fail("unexpected exception");
209 <        }
210 <    }
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 <    public void testReadAfterWriteLock() {
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(){
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(){
369 >                public void run() {
370                      lock.readLock().lock();
371                      lock.readLock().unlock();
372                  }
373              });
374  
375 <        try {
376 <            t1.start();
377 <            t2.start();
378 <            Thread.sleep(SHORT_DELAY_MS);
379 <            lock.writeLock().unlock();
380 <            t1.join(MEDIUM_DELAY_MS);
381 <            t2.join(MEDIUM_DELAY_MS);
382 <            assertTrue(!t1.isAlive());
383 <            assertTrue(!t2.isAlive());
237 <          
238 <        } catch(Exception e){
239 <            fail("unexpected exception");
240 <        }
241 <    }
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 <    public void testTryLockWhenReadLocked() {
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 >        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 >
580 >
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 <                    assertTrue(lock.readLock().tryLock());
626 >                public void run() {
627 >                    threadAssertTrue(lock.readLock().tryLock());
628                      lock.readLock().unlock();
629                  }
630              });
253        try {
254            t.start();
255            t.join();
256            lock.readLock().unlock();
257        } catch(Exception e){
258            fail("unexpected exception");
259        }
260    }
631  
632 <    
632 >        t.start();
633 >        t.join();
634 >        lock.readLock().unlock();
635 >    }
636 >
637  
638 <    public void testWriteTryLockWhenReadLocked() {
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 <                    assertFalse(lock.writeLock().tryLock());
646 >                public void run() {
647 >                    threadAssertFalse(lock.writeLock().tryLock());
648                  }
649              });
272        try {
273            t.start();
274            t.join();
275            lock.readLock().unlock();
276        } catch(Exception e){
277            fail("unexpected exception");
278        }
279    }
650  
651 <    
651 >        t.start();
652 >        t.join();
653 >        lock.readLock().unlock();
654 >    }
655 >
656  
657 <    public void testTryLock_Timeout(){
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(){
703 >                public void run() {
704                      try {
705 <                        assertFalse(lock.writeLock().tryLock(1, TimeUnit.MILLISECONDS));
705 >                        threadAssertFalse(lock.writeLock().tryLock(1, TimeUnit.MILLISECONDS));
706                      } catch (Exception ex) {
707 <                        fail("unexpected exception");
707 >                        threadUnexpectedException();
708                      }
709                  }
710              });
295        try {
296            t.start();
297            t.join();
298            lock.writeLock().unlock();
299        } catch(Exception e){
300            fail("unexpected exception");
301        }
302    }
711  
712 <    public void testTryLock_Timeout2(){
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(){
724 >                public void run() {
725                      try {
726 <                        assertFalse(lock.readLock().tryLock(1, TimeUnit.MILLISECONDS));
726 >                        threadAssertFalse(lock.readLock().tryLock(1, TimeUnit.MILLISECONDS));
727                      } catch (Exception ex) {
728 <                        fail("unexpected exception");
728 >                        threadUnexpectedException();
729                      }
730                  }
731              });
732 <        try {
733 <            t.start();
734 <            t.join();
735 <            lock.writeLock().unlock();
736 <        } catch(Exception e){
321 <            fail("unexpected exception");
322 <        }
323 <    }
732 >
733 >        t.start();
734 >        t.join();
735 >        lock.writeLock().unlock();
736 >    }
737  
738  
739 <    public void testLockInterruptibly() {
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 <        try {
745 <            lock.writeLock().lockInterruptibly();
330 <        } catch(Exception e) {
331 <            fail("unexpected exception");
332 <        }
333 <        Thread t = new Thread(new Runnable() {
744 >        lock.writeLock().lockInterruptibly();
745 >        Thread t = new Thread(new Runnable() {
746                  public void run() {
747                      try {
748                          lock.writeLock().lockInterruptibly();
749 <                        fail("should throw");
749 >                        threadShouldThrow();
750                      }
751 <                    catch(InterruptedException success) {
751 >                    catch (InterruptedException success) {
752                      }
753                  }
754              });
755 <        try {
756 <            t.start();
757 <            t.interrupt();
758 <            t.join();
759 <            lock.writeLock().unlock();
760 <        } catch(Exception e){
761 <            fail("unexpected exception");
350 <        }
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 <    public void testLockInterruptibly2() {
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 <        try {
770 <            lock.writeLock().lockInterruptibly();
357 <        } catch(Exception e) {
358 <            fail("unexpected exception");
359 <        }
360 <        Thread t = new Thread(new Runnable() {
769 >        lock.writeLock().lockInterruptibly();
770 >        Thread t = new Thread(new Runnable() {
771                  public void run() {
772                      try {
773                          lock.readLock().lockInterruptibly();
774 <                        fail("should throw");
774 >                        threadShouldThrow();
775                      }
776 <                    catch(InterruptedException success) {
776 >                    catch (InterruptedException success) {
777                      }
778                  }
779              });
780 <        try {
781 <            t.start();
782 <            t.interrupt();
783 <            t.join();
784 <            lock.writeLock().unlock();
785 <        } catch(Exception e){
376 <            fail("unexpected exception");
377 <        }
780 >
781 >        t.start();
782 >        Thread.sleep(SHORT_DELAY_MS);
783 >        t.interrupt();
784 >        t.join();
785 >        lock.writeLock().unlock();
786      }
787  
788 <    public void testAwait_IllegalMonitor() {
789 <        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
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 <            fail("should throw");
797 <        }
387 <        catch (IllegalMonitorStateException success) {
388 <        }
389 <        catch (Exception ex) {
390 <            fail("should throw IMSE");
391 <        }
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();      
804 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
805          final Condition c = lock.writeLock().newCondition();
806          try {
807              c.signal();
808 <            fail("should throw");
809 <        }
401 <        catch (IllegalMonitorStateException success) {
402 <        }
403 <        catch (Exception ex) {
404 <            fail("should throw IMSE");
405 <        }
808 >            shouldThrow();
809 >        } catch (IllegalMonitorStateException success) {}
810      }
811  
812 <    public void testAwaitNanos_Timeout() {
813 <        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
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 <        try {
819 <            lock.writeLock().lock();
820 <            long t = c.awaitNanos(100);
821 <            assertTrue(t <= 0);
822 <            lock.writeLock().unlock();
416 <        }
417 <        catch (Exception ex) {
418 <            fail("unexpected exception");
419 <        }
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();      
830 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
831          final Condition c = lock.writeLock().newCondition();
832 <        try {
833 <            lock.writeLock().lock();
427 <            assertFalse(c.await(10, TimeUnit.MILLISECONDS));
428 <            lock.writeLock().unlock();
429 <        }
430 <        catch (Exception ex) {
431 <            fail("unexpected exception");
432 <        }
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();      
840 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
841          final Condition c = lock.writeLock().newCondition();
842 <        try {
843 <            lock.writeLock().lock();
844 <            java.util.Date d = new java.util.Date();
441 <            assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
442 <            lock.writeLock().unlock();
443 <        }
444 <        catch (Exception ex) {
445 <            fail("unexpected exception");
446 <        }
842 >        lock.writeLock().lock();
843 >        java.util.Date d = new java.util.Date();
844 >        lock.writeLock().unlock();
845      }
846  
847 <    public void testAwait() {
848 <        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
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() {
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) {
861 <                        fail("unexpected exception");
860 >                    catch (InterruptedException e) {
861 >                        threadUnexpectedException();
862                      }
863                  }
864              });
865  
866 <        try {
867 <            t.start();
868 <            Thread.sleep(SHORT_DELAY_MS);
869 <            lock.writeLock().lock();
870 <            c.signal();
871 <            lock.writeLock().unlock();
872 <            t.join(SHORT_DELAY_MS);
873 <            assertFalse(t.isAlive());
874 <        }
875 <        catch (Exception ex) {
876 <            fail("unexpected exception");
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 <    public void testAwaitUninterruptibly() {
903 <        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
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 <        Thread t = new Thread(new Runnable() {
483 <                public void run() {
484 <                    lock.writeLock().lock();
485 <                    c.awaitUninterruptibly();
486 <                    lock.writeLock().unlock();
487 <                }
488 <            });
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 <            t.start();
919 <            Thread.sleep(SHORT_DELAY_MS);
493 <            t.interrupt();
494 <            lock.writeLock().lock();
918 >            thread.interrupt();
919 >            thread.canAwake = true;
920              c.signal();
921 +        } finally {
922              lock.writeLock().unlock();
497            t.join(SHORT_DELAY_MS);
498            assertFalse(t.isAlive());
499        }
500        catch (Exception ex) {
501            fail("unexpected exception");
923          }
924 +
925 +        thread.join();
926 +        assertTrue(thread.interrupted);
927 +        assertFalse(thread.isAlive());
928      }
929  
930 <    public void testAwait_Interrupt() {
931 <        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
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() {
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 <                        fail("should throw");
942 >                        threadShouldThrow();
943                      }
944 <                    catch(InterruptedException success) {
944 >                    catch (InterruptedException success) {
945                      }
946                  }
947              });
948  
949 <        try {
950 <            t.start();
951 <            Thread.sleep(SHORT_DELAY_MS);
952 <            t.interrupt();
953 <            t.join(SHORT_DELAY_MS);
526 <            assertFalse(t.isAlive());
527 <        }
528 <        catch (Exception ex) {
529 <            fail("unexpected exception");
530 <        }
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 <    public void testAwaitNanos_Interrupt() {
957 <        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
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() {
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 <                        fail("should throw");
968 >                        threadShouldThrow();
969                      }
970 <                    catch(InterruptedException success) {
970 >                    catch (InterruptedException success) {
971                      }
972                  }
973              });
974  
975 <        try {
976 <            t.start();
977 <            Thread.sleep(SHORT_DELAY_MS);
978 <            t.interrupt();
979 <            t.join(SHORT_DELAY_MS);
554 <            assertFalse(t.isAlive());
555 <        }
556 <        catch (Exception ex) {
557 <            fail("unexpected exception");
558 <        }
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 <    public void testAwaitUntil_Interrupt() {
983 <        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
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() {
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 <                        fail("should throw");
995 >                        threadShouldThrow();
996                      }
997 <                    catch(InterruptedException success) {
997 >                    catch (InterruptedException success) {
998                      }
999                  }
1000              });
1001  
1002 <        try {
1003 <            t.start();
1004 <            Thread.sleep(SHORT_DELAY_MS);
1005 <            t.interrupt();
1006 <            t.join(SHORT_DELAY_MS);
583 <            assertFalse(t.isAlive());
584 <        }
585 <        catch (Exception ex) {
586 <            fail("unexpected exception");
587 <        }
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 <    public void testSignalAll() {
1010 <        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
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() {
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 <                        fail("unexpected exception");
1022 >                    catch (InterruptedException e) {
1023 >                        threadUnexpectedException();
1024                      }
1025                  }
1026              });
1027  
1028 <        Thread t2 = new Thread(new Runnable() {
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 <                        fail("unexpected exception");
1035 >                    catch (InterruptedException e) {
1036 >                        threadUnexpectedException();
1037                      }
1038                  }
1039              });
1040  
1041 <        try {
1042 <            t1.start();
1043 <            t2.start();
1044 <            Thread.sleep(SHORT_DELAY_MS);
1045 <            lock.writeLock().lock();
1046 <            c.signalAll();
1047 <            lock.writeLock().unlock();
1048 <            t1.join(SHORT_DELAY_MS);
1049 <            t2.join(SHORT_DELAY_MS);
1050 <            assertFalse(t1.isAlive());
629 <            assertFalse(t2.isAlive());
630 <        }
631 <        catch (Exception ex) {
632 <            fail("unexpected exception");
633 <        }
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 <    public void testSerialization() {
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 <            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
1105 <            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
1106 <            out.writeObject(l);
645 <            out.close();
646 <
647 <            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
648 <            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
649 <            ReentrantReadWriteLock r = (ReentrantReadWriteLock) in.readObject();
650 <            r.readLock().lock();
651 <            r.readLock().unlock();
652 <        } catch(Exception e){
653 <            e.printStackTrace();
654 <            fail("unexpected exception");
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 +    }
1483  
1484   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines