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.17 by dl, Thu Jan 8 01:29:46 2004 UTC

# Line 1 | Line 1
1   /*
2 < * Written by members of JCP JSR-166 Expert Group and released to the
3 < * public domain. Use, modify, and redistribute this code in any way
4 < * without acknowledgement. Other contributors include Andrew Wright,
5 < * Jeffrey Hayes, Pat Fischer, Mike Judd.
2 > * Written by Doug Lea with assistance from members of JCP JSR-166
3 > * Expert Group and released to the public domain, as explained at
4 > * http://creativecommons.org/licenses/publicdomain
5 > * Other contributors include Andrew Wright, Jeffrey Hayes,
6 > * Pat Fisher, Mike Judd.
7   */
8  
9   import junit.framework.*;
10   import java.util.concurrent.locks.*;
11   import java.util.concurrent.*;
12 + import java.io.*;
13 + import java.util.*;
14  
15 < public class ReentrantReadWriteLockTest extends TestCase {
13 <    static int HOLD_COUNT_TEST_LIMIT = 20;
14 <    
15 > public class ReentrantReadWriteLockTest extends JSR166TestCase {
16      public static void main(String[] args) {
17          junit.textui.TestRunner.run (suite());  
18      }
18    
19      public static Test suite() {
20          return new TestSuite(ReentrantReadWriteLockTest.class);
21      }
22  
23 +    /**
24 +     * A runnable calling lockInterruptibly
25 +     */
26 +    class InterruptibleLockRunnable implements Runnable {
27 +        final ReentrantReadWriteLock lock;
28 +        InterruptibleLockRunnable(ReentrantReadWriteLock l) { lock = l; }
29 +        public void run() {
30 +            try {
31 +                lock.writeLock().lockInterruptibly();
32 +            } catch(InterruptedException success){}
33 +        }
34 +    }
35 +
36 +
37 +    /**
38 +     * A runnable calling lockInterruptibly that expects to be
39 +     * interrupted
40 +     */
41 +    class InterruptedLockRunnable implements Runnable {
42 +        final ReentrantReadWriteLock lock;
43 +        InterruptedLockRunnable(ReentrantReadWriteLock l) { lock = l; }
44 +        public void run() {
45 +            try {
46 +                lock.writeLock().lockInterruptibly();
47 +                threadShouldThrow();
48 +            } catch(InterruptedException success){}
49 +        }
50 +    }
51 +
52 +    /**
53 +     * Subclass to expose protected methods
54 +     */
55 +    static class PublicReentrantReadWriteLock extends ReentrantReadWriteLock {
56 +        PublicReentrantReadWriteLock() { super(); }
57 +        public Collection<Thread> getQueuedThreads() {
58 +            return super.getQueuedThreads();
59 +        }
60 +        public Collection<Thread> getWaitingThreads(Condition c) {
61 +            return super.getWaitingThreads(c);
62 +        }
63 +    }
64 +
65 +    /**
66 +     * Constructor sets given fairness, and is in unlocked state
67 +     */
68 +    public void testConstructor() {
69 +        ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
70 +        assertFalse(rl.isFair());
71 +        assertFalse(rl.isWriteLocked());
72 +        assertEquals(0, rl.getReadLockCount());
73 +        ReentrantReadWriteLock r2 = new ReentrantReadWriteLock(true);
74 +        assertTrue(r2.isFair());
75 +        assertFalse(r2.isWriteLocked());
76 +        assertEquals(0, r2.getReadLockCount());
77 +    }
78 +
79 +    /**
80 +     * write-locking and read-locking an unlocked lock succeed
81 +     */
82 +    public void testLock() {
83 +        ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
84 +        rl.writeLock().lock();
85 +        assertTrue(rl.isWriteLocked());
86 +        assertTrue(rl.isWriteLockedByCurrentThread());
87 +        assertEquals(0, rl.getReadLockCount());
88 +        rl.writeLock().unlock();
89 +        assertFalse(rl.isWriteLocked());
90 +        assertFalse(rl.isWriteLockedByCurrentThread());
91 +        assertEquals(0, rl.getReadLockCount());
92 +        rl.readLock().lock();
93 +        assertFalse(rl.isWriteLocked());
94 +        assertFalse(rl.isWriteLockedByCurrentThread());
95 +        assertEquals(1, rl.getReadLockCount());
96 +        rl.readLock().unlock();
97 +        assertFalse(rl.isWriteLocked());
98 +        assertFalse(rl.isWriteLockedByCurrentThread());
99 +        assertEquals(0, rl.getReadLockCount());
100 +    }
101 +
102  
103 <    private static long SHORT_DELAY_MS = 100;
104 <    private static long MEDIUM_DELAY_MS = 1000;
26 <    private static long LONG_DELAY_MS = 10000;
27 <
28 <    /*
29 <     * Unlocks an unlocked lock, throws Illegal Monitor State
30 <     *
103 >    /**
104 >     * locking an unlocked fair lock succeeds
105       */
106 +    public void testFairLock() {
107 +        ReentrantReadWriteLock rl = new ReentrantReadWriteLock(true);
108 +        rl.writeLock().lock();
109 +        assertTrue(rl.isWriteLocked());
110 +        assertTrue(rl.isWriteLockedByCurrentThread());
111 +        assertEquals(0, rl.getReadLockCount());
112 +        rl.writeLock().unlock();
113 +        assertFalse(rl.isWriteLocked());
114 +        assertFalse(rl.isWriteLockedByCurrentThread());
115 +        assertEquals(0, rl.getReadLockCount());
116 +        rl.readLock().lock();
117 +        assertFalse(rl.isWriteLocked());
118 +        assertFalse(rl.isWriteLockedByCurrentThread());
119 +        assertEquals(1, rl.getReadLockCount());
120 +        rl.readLock().unlock();
121 +        assertFalse(rl.isWriteLocked());
122 +        assertFalse(rl.isWriteLockedByCurrentThread());
123 +        assertEquals(0, rl.getReadLockCount());
124 +    }
125 +
126 +    /**
127 +     * getWriteHoldCount returns number of recursive holds
128 +     */
129 +    public void testGetHoldCount() {
130 +        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
131 +        for(int i = 1; i <= SIZE; i++) {
132 +            lock.writeLock().lock();
133 +            assertEquals(i,lock.getWriteHoldCount());
134 +        }
135 +        for(int i = SIZE; i > 0; i--) {
136 +            lock.writeLock().unlock();
137 +            assertEquals(i-1,lock.getWriteHoldCount());
138 +        }
139 +    }
140      
141 <    public void testIllegalMonitorStateException(){
141 >
142 >    /**
143 >     * write-unlocking an unlocked lock throws IllegalMonitorStateException
144 >     */
145 >    public void testUnlock_IllegalMonitorStateException() {
146          ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
147 <        try{
147 >        try {
148              rl.writeLock().unlock();
149 <            fail("Should of thown Illegal Monitor State Exception");
149 >            shouldThrow();
150 >        } catch(IllegalMonitorStateException success){}
151 >    }
152  
39        }catch(IllegalMonitorStateException sucess){}
153  
154 +    /**
155 +     * write-lockInterruptibly is interruptible
156 +     */
157 +    public void testWriteLockInterruptibly_Interrupted() {
158 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
159 +        Thread t = new Thread(new Runnable() {
160 +                public void run() {
161 +                    try {
162 +                        lock.writeLock().lockInterruptibly();
163 +                        lock.writeLock().unlock();
164 +                        lock.writeLock().lockInterruptibly();
165 +                        lock.writeLock().unlock();
166 +                    } catch(InterruptedException success){}
167 +                }
168 +            });
169 +        try {
170 +            lock.writeLock().lock();
171 +            t.start();
172 +            t.interrupt();
173 +            lock.writeLock().unlock();
174 +            t.join();
175 +        } catch(Exception e){
176 +            unexpectedException();
177 +        }
178 +    }
179  
180 +    /**
181 +     * timed write-tryLock is interruptible
182 +     */
183 +    public void testWriteTryLock_Interrupted() {
184 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
185 +        lock.writeLock().lock();
186 +        Thread t = new Thread(new Runnable() {
187 +                public void run() {
188 +                    try {
189 +                        lock.writeLock().tryLock(1000,TimeUnit.MILLISECONDS);
190 +                    } catch(InterruptedException success){}
191 +                }
192 +            });
193 +        try {
194 +            t.start();
195 +            t.interrupt();
196 +            lock.writeLock().unlock();
197 +            t.join();
198 +        } catch(Exception e){
199 +            unexpectedException();
200 +        }
201 +    }
202 +
203 +    /**
204 +     * read-lockInterruptibly is interruptible
205 +     */
206 +    public void testReadLockInterruptibly_Interrupted() {
207 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
208 +        lock.writeLock().lock();
209 +        Thread t = new Thread(new Runnable() {
210 +                public void run() {
211 +                    try {
212 +                        lock.readLock().lockInterruptibly();
213 +                    } catch(InterruptedException success){}
214 +                }
215 +            });
216 +        try {
217 +            t.start();
218 +            t.interrupt();
219 +            lock.writeLock().unlock();
220 +            t.join();
221 +        } catch(Exception e){
222 +            unexpectedException();
223 +        }
224 +    }
225 +
226 +    /**
227 +     * timed read-tryLock is interruptible
228 +     */
229 +    public void testReadTryLock_Interrupted() {
230 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
231 +        lock.writeLock().lock();
232 +        Thread t = new Thread(new Runnable() {
233 +                public void run() {
234 +                    try {
235 +                        lock.readLock().tryLock(1000,TimeUnit.MILLISECONDS);
236 +                        threadShouldThrow();
237 +                    } catch(InterruptedException success){}
238 +                }
239 +            });
240 +        try {
241 +            t.start();
242 +            t.interrupt();
243 +            t.join();
244 +        } catch(Exception e){
245 +            unexpectedException();
246 +        }
247      }
248 +
249      
250 <    /*
251 <     * makes a lock, locks it, tries to aquire the lock in another thread
46 <     * interrupts that thread and waits for an interrupted Exception to
47 <     * be thrown.
250 >    /**
251 >     * write-tryLock fails if locked
252       */
253 +    public void testWriteTryLockWhenLocked() {
254 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
255 +        lock.writeLock().lock();
256 +        Thread t = new Thread(new Runnable() {
257 +                public void run() {
258 +                    threadAssertFalse(lock.writeLock().tryLock());
259 +                }
260 +            });
261 +        try {
262 +            t.start();
263 +            t.join();
264 +            lock.writeLock().unlock();
265 +        } catch(Exception e){
266 +            unexpectedException();
267 +        }
268 +    }
269  
270 <    public void testInterruptedException(){
270 >    /**
271 >     * read-tryLock fails if locked
272 >     */
273 >    public void testReadTryLockWhenLocked() {
274          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
275          lock.writeLock().lock();
276          Thread t = new Thread(new Runnable() {
277 <                public void run(){
278 <                    try{
279 <                        lock.writeLock().lockInterruptibly();
280 <                        fail("should throw");
281 <                    }catch(InterruptedException sucess){}
277 >                public void run() {
278 >                    threadAssertFalse(lock.readLock().tryLock());
279 >                }
280 >            });
281 >        try {
282 >            t.start();
283 >            t.join();
284 >            lock.writeLock().unlock();
285 >        } catch(Exception e){
286 >            unexpectedException();
287 >        }
288 >    }
289 >
290 >    /**
291 >     * Multiple threads can hold a read lock when not write-locked
292 >     */
293 >    public void testMultipleReadLocks() {
294 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
295 >        lock.readLock().lock();
296 >        Thread t = new Thread(new Runnable() {
297 >                public void run() {
298 >                    threadAssertTrue(lock.readLock().tryLock());
299 >                    lock.readLock().unlock();
300 >                }
301 >            });
302 >        try {
303 >            t.start();
304 >            t.join();
305 >            lock.readLock().unlock();
306 >        } catch(Exception e){
307 >            unexpectedException();
308 >        }
309 >    }
310 >
311 >    /**
312 >     * A writelock succeeds after reading threads unlock
313 >     */
314 >    public void testWriteAfterMultipleReadLocks() {
315 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
316 >        lock.readLock().lock();
317 >        Thread t1 = new Thread(new Runnable() {
318 >                public void run() {
319 >                    lock.readLock().lock();
320 >                    lock.readLock().unlock();
321 >                }
322 >            });
323 >        Thread t2 = new Thread(new Runnable() {
324 >                public void run() {
325 >                    lock.writeLock().lock();
326 >                    lock.writeLock().unlock();
327 >                }
328 >            });
329 >
330 >        try {
331 >            t1.start();
332 >            t2.start();
333 >            Thread.sleep(SHORT_DELAY_MS);
334 >            lock.readLock().unlock();
335 >            t1.join(MEDIUM_DELAY_MS);
336 >            t2.join(MEDIUM_DELAY_MS);
337 >            assertTrue(!t1.isAlive());
338 >            assertTrue(!t2.isAlive());
339 >          
340 >        } catch(Exception e){
341 >            unexpectedException();
342 >        }
343 >    }
344 >
345 >    /**
346 >     * Readlocks succeed after a writing thread unlocks
347 >     */
348 >    public void testReadAfterWriteLock() {
349 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
350 >        lock.writeLock().lock();
351 >        Thread t1 = new Thread(new Runnable() {
352 >                public void run() {
353 >                    lock.readLock().lock();
354 >                    lock.readLock().unlock();
355 >                }
356 >            });
357 >        Thread t2 = new Thread(new Runnable() {
358 >                public void run() {
359 >                    lock.readLock().lock();
360 >                    lock.readLock().unlock();
361 >                }
362 >            });
363 >
364 >        try {
365 >            t1.start();
366 >            t2.start();
367 >            Thread.sleep(SHORT_DELAY_MS);
368 >            lock.writeLock().unlock();
369 >            t1.join(MEDIUM_DELAY_MS);
370 >            t2.join(MEDIUM_DELAY_MS);
371 >            assertTrue(!t1.isAlive());
372 >            assertTrue(!t2.isAlive());
373 >          
374 >        } catch(Exception e){
375 >            unexpectedException();
376 >        }
377 >    }
378 >
379 >
380 >    /**
381 >     * Read tryLock succeeds if readlocked but not writelocked
382 >     */
383 >    public void testTryLockWhenReadLocked() {
384 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
385 >        lock.readLock().lock();
386 >        Thread t = new Thread(new Runnable() {
387 >                public void run() {
388 >                    threadAssertTrue(lock.readLock().tryLock());
389 >                    lock.readLock().unlock();
390                  }
391              });
392 <        t.start();
393 <        t.interrupt();
394 <        lock.writeLock().unlock();
392 >        try {
393 >            t.start();
394 >            t.join();
395 >            lock.readLock().unlock();
396 >        } catch(Exception e){
397 >            unexpectedException();
398 >        }
399      }
400  
401 <    /*
402 <     * tests for interrupted exception on a timed wait
403 <     *
401 >    
402 >
403 >    /**
404 >     * write tryLock fails when readlocked
405       */
406 +    public void testWriteTryLockWhenReadLocked() {
407 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
408 +        lock.readLock().lock();
409 +        Thread t = new Thread(new Runnable() {
410 +                public void run() {
411 +                    threadAssertFalse(lock.writeLock().tryLock());
412 +                }
413 +            });
414 +        try {
415 +            t.start();
416 +            t.join();
417 +            lock.readLock().unlock();
418 +        } catch(Exception e){
419 +            unexpectedException();
420 +        }
421 +    }
422 +
423      
424  
425 <    public void testInterruptedException2(){
425 >    /**
426 >     * write timed tryLock times out if locked
427 >     */
428 >    public void testWriteTryLock_Timeout() {
429          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
430          lock.writeLock().lock();
431          Thread t = new Thread(new Runnable() {
432 <                public void run(){
433 <                    try{
434 <                        lock.writeLock().tryLock(1000,TimeUnit.MILLISECONDS);
435 <                        fail("should throw");
436 <                    }catch(InterruptedException sucess){}
432 >                public void run() {
433 >                    try {
434 >                        threadAssertFalse(lock.writeLock().tryLock(1, TimeUnit.MILLISECONDS));
435 >                    } catch (Exception ex) {
436 >                        threadUnexpectedException();
437 >                    }
438                  }
439              });
440 <        t.start();
441 <        t.interrupt();
440 >        try {
441 >            t.start();
442 >            t.join();
443 >            lock.writeLock().unlock();
444 >        } catch(Exception e){
445 >            unexpectedException();
446 >        }
447 >    }
448 >
449 >    /**
450 >     * read timed tryLock times out if write-locked
451 >     */
452 >    public void testReadTryLock_Timeout() {
453 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
454 >        lock.writeLock().lock();
455 >        Thread t = new Thread(new Runnable() {
456 >                public void run() {
457 >                    try {
458 >                        threadAssertFalse(lock.readLock().tryLock(1, TimeUnit.MILLISECONDS));
459 >                    } catch (Exception ex) {
460 >                        threadUnexpectedException();
461 >                    }
462 >                }
463 >            });
464 >        try {
465 >            t.start();
466 >            t.join();
467 >            lock.writeLock().unlock();
468 >        } catch(Exception e){
469 >            unexpectedException();
470 >        }
471 >    }
472 >
473 >
474 >    /**
475 >     * write lockInterruptibly succeeds if lock free else is interruptible
476 >     */
477 >    public void testWriteLockInterruptibly() {
478 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
479 >        try {
480 >            lock.writeLock().lockInterruptibly();
481 >        } catch(Exception e) {
482 >            unexpectedException();
483 >        }
484 >        Thread t = new Thread(new Runnable() {
485 >                public void run() {
486 >                    try {
487 >                        lock.writeLock().lockInterruptibly();
488 >                        threadShouldThrow();
489 >                    }
490 >                    catch(InterruptedException success) {
491 >                    }
492 >                }
493 >            });
494 >        try {
495 >            t.start();
496 >            t.interrupt();
497 >            t.join();
498 >            lock.writeLock().unlock();
499 >        } catch(Exception e){
500 >            unexpectedException();
501 >        }
502      }
503  
504 <    
504 >    /**
505 >     *  read lockInterruptibly succeeds if lock free else is interruptible
506 >     */
507 >    public void testReadLockInterruptibly() {
508 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
509 >        try {
510 >            lock.writeLock().lockInterruptibly();
511 >        } catch(Exception e) {
512 >            unexpectedException();
513 >        }
514 >        Thread t = new Thread(new Runnable() {
515 >                public void run() {
516 >                    try {
517 >                        lock.readLock().lockInterruptibly();
518 >                        threadShouldThrow();
519 >                    }
520 >                    catch(InterruptedException success) {
521 >                    }
522 >                }
523 >            });
524 >        try {
525 >            t.start();
526 >            t.interrupt();
527 >            t.join();
528 >            lock.writeLock().unlock();
529 >        } catch(Exception e){
530 >            unexpectedException();
531 >        }
532 >    }
533  
534 <    /*
535 <     * current thread locks interruptibly the thread
91 <     * another thread tries to aquire the lock and blocks
92 <     * on the call. interrupt the attempted aquireLock
93 <     * assert that the first lock() call actually locked the lock
94 <     * assert that the current thread is the one holding the lock
534 >    /**
535 >     * Calling await without holding lock throws IllegalMonitorStateException
536       */
537 +    public void testAwait_IllegalMonitor() {
538 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
539 +        final Condition c = lock.writeLock().newCondition();
540 +        try {
541 +            c.await();
542 +            shouldThrow();
543 +        }
544 +        catch (IllegalMonitorStateException success) {
545 +        }
546 +        catch (Exception ex) {
547 +            shouldThrow();
548 +        }
549 +    }
550  
551 <    public void testLockedInterruptibly() {
551 >    /**
552 >     * Calling signal without holding lock throws IllegalMonitorStateException
553 >     */
554 >    public void testSignal_IllegalMonitor() {
555          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
556 <        try {lock.writeLock().lockInterruptibly();} catch(Exception e) {}
556 >        final Condition c = lock.writeLock().newCondition();
557 >        try {
558 >            c.signal();
559 >            shouldThrow();
560 >        }
561 >        catch (IllegalMonitorStateException success) {
562 >        }
563 >        catch (Exception ex) {
564 >            unexpectedException();
565 >        }
566 >    }
567 >
568 >    /**
569 >     * awaitNanos without a signal times out
570 >     */
571 >    public void testAwaitNanos_Timeout() {
572 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
573 >        final Condition c = lock.writeLock().newCondition();
574 >        try {
575 >            lock.writeLock().lock();
576 >            long t = c.awaitNanos(100);
577 >            assertTrue(t <= 0);
578 >            lock.writeLock().unlock();
579 >        }
580 >        catch (Exception ex) {
581 >            unexpectedException();
582 >        }
583 >    }
584 >
585 >
586 >    /**
587 >     *  timed await without a signal times out
588 >     */
589 >    public void testAwait_Timeout() {
590 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
591 >        final Condition c = lock.writeLock().newCondition();
592 >        try {
593 >            lock.writeLock().lock();
594 >            assertFalse(c.await(10, TimeUnit.MILLISECONDS));
595 >            lock.writeLock().unlock();
596 >        }
597 >        catch (Exception ex) {
598 >            unexpectedException();
599 >        }
600 >    }
601 >
602 >    /**
603 >     * awaitUntil without a signal times out
604 >     */
605 >    public void testAwaitUntil_Timeout() {
606 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
607 >        final Condition c = lock.writeLock().newCondition();
608 >        try {
609 >            lock.writeLock().lock();
610 >            java.util.Date d = new java.util.Date();
611 >            assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
612 >            lock.writeLock().unlock();
613 >        }
614 >        catch (Exception ex) {
615 >            unexpectedException();
616 >        }
617 >    }
618 >
619 >    /**
620 >     * await returns when signalled
621 >     */
622 >    public void testAwait() {
623 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
624 >        final Condition c = lock.writeLock().newCondition();
625          Thread t = new Thread(new Runnable() {
626                  public void run() {
627                      try {
628 <                        lock.writeLock().lockInterruptibly();
629 <                        fail("Failed to generate an Interrupted Exception");
628 >                        lock.writeLock().lock();
629 >                        c.await();
630 >                        lock.writeLock().unlock();
631                      }
632 <                    catch(InterruptedException e) {}
632 >                    catch(InterruptedException e) {
633 >                        threadUnexpectedException();
634 >                    }
635                  }
636              });
637 <        t.start();
638 <        t.interrupt();
637 >
638 >        try {
639 >            t.start();
640 >            Thread.sleep(SHORT_DELAY_MS);
641 >            lock.writeLock().lock();
642 >            c.signal();
643 >            lock.writeLock().unlock();
644 >            t.join(SHORT_DELAY_MS);
645 >            assertFalse(t.isAlive());
646 >        }
647 >        catch (Exception ex) {
648 >            unexpectedException();
649 >        }
650 >    }
651 >
652 >    /**
653 >     * awaitUninterruptibly doesn't abort on interrupt
654 >     */
655 >    public void testAwaitUninterruptibly() {
656 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
657 >        final Condition c = lock.writeLock().newCondition();
658 >        Thread t = new Thread(new Runnable() {
659 >                public void run() {
660 >                    lock.writeLock().lock();
661 >                    c.awaitUninterruptibly();
662 >                    lock.writeLock().unlock();
663 >                }
664 >            });
665 >
666 >        try {
667 >            t.start();
668 >            Thread.sleep(SHORT_DELAY_MS);
669 >            t.interrupt();
670 >            lock.writeLock().lock();
671 >            c.signal();
672 >            lock.writeLock().unlock();
673 >            assert(t.isInterrupted());
674 >            t.join(SHORT_DELAY_MS);
675 >            assertFalse(t.isAlive());
676 >        }
677 >        catch (Exception ex) {
678 >            unexpectedException();
679 >        }
680 >    }
681 >
682 >    /**
683 >     * await is interruptible
684 >     */
685 >    public void testAwait_Interrupt() {
686 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
687 >        final Condition c = lock.writeLock().newCondition();
688 >        Thread t = new Thread(new Runnable() {
689 >                public void run() {
690 >                    try {
691 >                        lock.writeLock().lock();
692 >                        c.await();
693 >                        lock.writeLock().unlock();
694 >                        threadShouldThrow();
695 >                    }
696 >                    catch(InterruptedException success) {
697 >                    }
698 >                }
699 >            });
700 >
701 >        try {
702 >            t.start();
703 >            Thread.sleep(SHORT_DELAY_MS);
704 >            t.interrupt();
705 >            t.join(SHORT_DELAY_MS);
706 >            assertFalse(t.isAlive());
707 >        }
708 >        catch (Exception ex) {
709 >            unexpectedException();
710 >        }
711 >    }
712 >
713 >    /**
714 >     * awaitNanos is interruptible
715 >     */
716 >    public void testAwaitNanos_Interrupt() {
717 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
718 >        final Condition c = lock.writeLock().newCondition();
719 >        Thread t = new Thread(new Runnable() {
720 >                public void run() {
721 >                    try {
722 >                        lock.writeLock().lock();
723 >                        c.awaitNanos(SHORT_DELAY_MS * 2 * 1000000);
724 >                        lock.writeLock().unlock();
725 >                        threadShouldThrow();
726 >                    }
727 >                    catch(InterruptedException success) {
728 >                    }
729 >                }
730 >            });
731 >
732 >        try {
733 >            t.start();
734 >            Thread.sleep(SHORT_DELAY_MS);
735 >            t.interrupt();
736 >            t.join(SHORT_DELAY_MS);
737 >            assertFalse(t.isAlive());
738 >        }
739 >        catch (Exception ex) {
740 >            unexpectedException();
741 >        }
742 >    }
743 >
744 >    /**
745 >     * awaitUntil is interruptible
746 >     */
747 >    public void testAwaitUntil_Interrupt() {
748 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
749 >        final Condition c = lock.writeLock().newCondition();
750 >        Thread t = new Thread(new Runnable() {
751 >                public void run() {
752 >                    try {
753 >                        lock.writeLock().lock();
754 >                        java.util.Date d = new java.util.Date();
755 >                        c.awaitUntil(new java.util.Date(d.getTime() + 10000));
756 >                        lock.writeLock().unlock();
757 >                        threadShouldThrow();
758 >                    }
759 >                    catch(InterruptedException success) {
760 >                    }
761 >                }
762 >            });
763 >
764 >        try {
765 >            t.start();
766 >            Thread.sleep(SHORT_DELAY_MS);
767 >            t.interrupt();
768 >            t.join(SHORT_DELAY_MS);
769 >            assertFalse(t.isAlive());
770 >        }
771 >        catch (Exception ex) {
772 >            unexpectedException();
773 >        }
774 >    }
775 >
776 >    /**
777 >     * signalAll wakes up all threads
778 >     */
779 >    public void testSignalAll() {
780 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
781 >        final Condition c = lock.writeLock().newCondition();
782 >        Thread t1 = new Thread(new Runnable() {
783 >                public void run() {
784 >                    try {
785 >                        lock.writeLock().lock();
786 >                        c.await();
787 >                        lock.writeLock().unlock();
788 >                    }
789 >                    catch(InterruptedException e) {
790 >                        threadUnexpectedException();
791 >                    }
792 >                }
793 >            });
794 >
795 >        Thread t2 = new Thread(new Runnable() {
796 >                public void run() {
797 >                    try {
798 >                        lock.writeLock().lock();
799 >                        c.await();
800 >                        lock.writeLock().unlock();
801 >                    }
802 >                    catch(InterruptedException e) {
803 >                        threadUnexpectedException();
804 >                    }
805 >                }
806 >            });
807 >
808 >        try {
809 >            t1.start();
810 >            t2.start();
811 >            Thread.sleep(SHORT_DELAY_MS);
812 >            lock.writeLock().lock();
813 >            c.signalAll();
814 >            lock.writeLock().unlock();
815 >            t1.join(SHORT_DELAY_MS);
816 >            t2.join(SHORT_DELAY_MS);
817 >            assertFalse(t1.isAlive());
818 >            assertFalse(t2.isAlive());
819 >        }
820 >        catch (Exception ex) {
821 >            unexpectedException();
822 >        }
823 >    }
824 >
825 >    /**
826 >     * A serialized lock deserializes as unlocked
827 >     */
828 >    public void testSerialization() {
829 >        ReentrantReadWriteLock l = new ReentrantReadWriteLock();
830 >        l.readLock().lock();
831 >        l.readLock().unlock();
832 >
833 >        try {
834 >            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
835 >            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
836 >            out.writeObject(l);
837 >            out.close();
838 >
839 >            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
840 >            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
841 >            ReentrantReadWriteLock r = (ReentrantReadWriteLock) in.readObject();
842 >            r.readLock().lock();
843 >            r.readLock().unlock();
844 >        } catch(Exception e){
845 >            e.printStackTrace();
846 >            unexpectedException();
847 >        }
848 >    }
849 >
850 >    /**
851 >     * hasQueuedThreads reports whether there are waiting threads
852 >     */
853 >    public void testhasQueuedThreads() {
854 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
855 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
856 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
857 >        try {
858 >            assertFalse(lock.hasQueuedThreads());
859 >            lock.writeLock().lock();
860 >            t1.start();
861 >            Thread.sleep(SHORT_DELAY_MS);
862 >            assertTrue(lock.hasQueuedThreads());
863 >            t2.start();
864 >            Thread.sleep(SHORT_DELAY_MS);
865 >            assertTrue(lock.hasQueuedThreads());
866 >            t1.interrupt();
867 >            Thread.sleep(SHORT_DELAY_MS);
868 >            assertTrue(lock.hasQueuedThreads());
869 >            lock.writeLock().unlock();
870 >            Thread.sleep(SHORT_DELAY_MS);
871 >            assertFalse(lock.hasQueuedThreads());
872 >            t1.join();
873 >            t2.join();
874 >        } catch(Exception e){
875 >            unexpectedException();
876 >        }
877 >    }
878 >
879 >    /**
880 >     * getQueueLength reports number of waiting threads
881 >     */
882 >    public void testGetQueueLength() {
883 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
884 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
885 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
886 >        try {
887 >            assertEquals(0, lock.getQueueLength());
888 >            lock.writeLock().lock();
889 >            t1.start();
890 >            Thread.sleep(SHORT_DELAY_MS);
891 >            assertEquals(1, lock.getQueueLength());
892 >            t2.start();
893 >            Thread.sleep(SHORT_DELAY_MS);
894 >            assertEquals(2, lock.getQueueLength());
895 >            t1.interrupt();
896 >            Thread.sleep(SHORT_DELAY_MS);
897 >            assertEquals(1, lock.getQueueLength());
898 >            lock.writeLock().unlock();
899 >            Thread.sleep(SHORT_DELAY_MS);
900 >            assertEquals(0, lock.getQueueLength());
901 >            t1.join();
902 >            t2.join();
903 >        } catch(Exception e){
904 >            unexpectedException();
905 >        }
906 >    }
907 >
908 >    /**
909 >     * getQueuedThreads includes waiting threads
910 >     */
911 >    public void testGetQueuedThreads() {
912 >        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
913 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
914 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
915 >        try {
916 >            assertTrue(lock.getQueuedThreads().isEmpty());
917 >            lock.writeLock().lock();
918 >            assertTrue(lock.getQueuedThreads().isEmpty());
919 >            t1.start();
920 >            Thread.sleep(SHORT_DELAY_MS);
921 >            assertTrue(lock.getQueuedThreads().contains(t1));
922 >            t2.start();
923 >            Thread.sleep(SHORT_DELAY_MS);
924 >            assertTrue(lock.getQueuedThreads().contains(t1));
925 >            assertTrue(lock.getQueuedThreads().contains(t2));
926 >            t1.interrupt();
927 >            Thread.sleep(SHORT_DELAY_MS);
928 >            assertFalse(lock.getQueuedThreads().contains(t1));
929 >            assertTrue(lock.getQueuedThreads().contains(t2));
930 >            lock.writeLock().unlock();
931 >            Thread.sleep(SHORT_DELAY_MS);
932 >            assertTrue(lock.getQueuedThreads().isEmpty());
933 >            t1.join();
934 >            t2.join();
935 >        } catch(Exception e){
936 >            unexpectedException();
937 >        }
938 >    }
939 >
940 >    /**
941 >     * hasWaiters throws NPE if null
942 >     */
943 >    public void testHasWaitersNPE() {
944 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
945 >        try {
946 >            lock.hasWaiters(null);
947 >            shouldThrow();
948 >        } catch (NullPointerException success) {
949 >        } catch (Exception ex) {
950 >            unexpectedException();
951 >        }
952 >    }
953 >
954 >    /**
955 >     * getWaitQueueLength throws NPE if null
956 >     */
957 >    public void testGetWaitQueueLengthNPE() {
958 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
959 >        try {
960 >            lock.getWaitQueueLength(null);
961 >            shouldThrow();
962 >        } catch (NullPointerException success) {
963 >        } catch (Exception ex) {
964 >            unexpectedException();
965 >        }
966 >    }
967 >
968 >
969 >    /**
970 >     * getWaitingThreads throws NPE if null
971 >     */
972 >    public void testGetWaitingThreadsNPE() {
973 >        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
974 >        try {
975 >            lock.getWaitingThreads(null);
976 >            shouldThrow();
977 >        } catch (NullPointerException success) {
978 >        } catch (Exception ex) {
979 >            unexpectedException();
980 >        }
981 >    }
982 >
983 >    /**
984 >     * hasWaiters throws IAE if not owned
985 >     */
986 >    public void testHasWaitersIAE() {
987 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
988 >        final Condition c = (lock.writeLock().newCondition());
989 >        final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock();
990 >        try {
991 >            lock2.hasWaiters(c);
992 >            shouldThrow();
993 >        } catch (IllegalArgumentException success) {
994 >        } catch (Exception ex) {
995 >            unexpectedException();
996 >        }
997 >    }
998 >
999 >    /**
1000 >     * hasWaiters throws IMSE if not locked
1001 >     */
1002 >    public void testHasWaitersIMSE() {
1003 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1004 >        final Condition c = (lock.writeLock().newCondition());
1005 >        try {
1006 >            lock.hasWaiters(c);
1007 >            shouldThrow();
1008 >        } catch (IllegalMonitorStateException success) {
1009 >        } catch (Exception ex) {
1010 >            unexpectedException();
1011 >        }
1012 >    }
1013 >
1014 >
1015 >    /**
1016 >     * getWaitQueueLength throws IAE if not owned
1017 >     */
1018 >    public void testGetWaitQueueLengthIAE() {
1019 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1020 >        final Condition c = (lock.writeLock().newCondition());
1021 >        final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock();
1022 >        try {
1023 >            lock2.getWaitQueueLength(c);
1024 >            shouldThrow();
1025 >        } catch (IllegalArgumentException success) {
1026 >        } catch (Exception ex) {
1027 >            unexpectedException();
1028 >        }
1029 >    }
1030 >
1031 >    /**
1032 >     * getWaitQueueLength throws IMSE if not locked
1033 >     */
1034 >    public void testGetWaitQueueLengthIMSE() {
1035 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1036 >        final Condition c = (lock.writeLock().newCondition());
1037 >        try {
1038 >            lock.getWaitQueueLength(c);
1039 >            shouldThrow();
1040 >        } catch (IllegalMonitorStateException success) {
1041 >        } catch (Exception ex) {
1042 >            unexpectedException();
1043 >        }
1044 >    }
1045 >
1046 >
1047 >    /**
1048 >     * getWaitingThreads throws IAE if not owned
1049 >     */
1050 >    public void testGetWaitingThreadsIAE() {
1051 >        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();  
1052 >        final Condition c = (lock.writeLock().newCondition());
1053 >        final PublicReentrantReadWriteLock lock2 = new PublicReentrantReadWriteLock();  
1054 >        try {
1055 >            lock2.getWaitingThreads(c);
1056 >            shouldThrow();
1057 >        } catch (IllegalArgumentException success) {
1058 >        } catch (Exception ex) {
1059 >            unexpectedException();
1060 >        }
1061 >    }
1062 >
1063 >    /**
1064 >     * getWaitingThreads throws IMSE if not locked
1065 >     */
1066 >    public void testGetWaitingThreadsIMSE() {
1067 >        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();  
1068 >        final Condition c = (lock.writeLock().newCondition());
1069 >        try {
1070 >            lock.getWaitingThreads(c);
1071 >            shouldThrow();
1072 >        } catch (IllegalMonitorStateException success) {
1073 >        } catch (Exception ex) {
1074 >            unexpectedException();
1075 >        }
1076 >    }
1077 >
1078 >
1079 >    /**
1080 >     * hasWaiters returns true when a thread is waiting, else false
1081 >     */
1082 >    public void testHasWaiters() {
1083 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1084 >        final Condition c = (lock.writeLock().newCondition());
1085 >        Thread t = new Thread(new Runnable() {
1086 >                public void run() {
1087 >                    try {
1088 >                        lock.writeLock().lock();
1089 >                        threadAssertFalse(lock.hasWaiters(c));
1090 >                        threadAssertEquals(0, lock.getWaitQueueLength(c));
1091 >                        c.await();
1092 >                        lock.writeLock().unlock();
1093 >                    }
1094 >                    catch(InterruptedException e) {
1095 >                        threadUnexpectedException();
1096 >                    }
1097 >                }
1098 >            });
1099 >
1100 >        try {
1101 >            t.start();
1102 >            Thread.sleep(SHORT_DELAY_MS);
1103 >            lock.writeLock().lock();
1104 >            assertTrue(lock.hasWaiters(c));
1105 >            assertEquals(1, lock.getWaitQueueLength(c));
1106 >            c.signal();
1107 >            lock.writeLock().unlock();
1108 >            Thread.sleep(SHORT_DELAY_MS);
1109 >            lock.writeLock().lock();
1110 >            assertFalse(lock.hasWaiters(c));
1111 >            assertEquals(0, lock.getWaitQueueLength(c));
1112 >            lock.writeLock().unlock();
1113 >            t.join(SHORT_DELAY_MS);
1114 >            assertFalse(t.isAlive());
1115 >        }
1116 >        catch (Exception ex) {
1117 >            unexpectedException();
1118 >        }
1119 >    }
1120 >
1121 >    /**
1122 >     * getWaitQueueLength returns number of waiting threads
1123 >     */
1124 >    public void testGetWaitQueueLength() {
1125 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1126 >        final Condition c = (lock.writeLock().newCondition());
1127 >        Thread t = new Thread(new Runnable() {
1128 >                public void run() {
1129 >                    try {
1130 >                        lock.writeLock().lock();
1131 >                        threadAssertFalse(lock.hasWaiters(c));
1132 >                        threadAssertEquals(0, lock.getWaitQueueLength(c));
1133 >                        c.await();
1134 >                        lock.writeLock().unlock();
1135 >                    }
1136 >                    catch(InterruptedException e) {
1137 >                        threadUnexpectedException();
1138 >                    }
1139 >                }
1140 >            });
1141 >
1142 >        try {
1143 >            t.start();
1144 >            Thread.sleep(SHORT_DELAY_MS);
1145 >            lock.writeLock().lock();
1146 >            assertTrue(lock.hasWaiters(c));
1147 >            assertEquals(1, lock.getWaitQueueLength(c));
1148 >            c.signal();
1149 >            lock.writeLock().unlock();
1150 >            Thread.sleep(SHORT_DELAY_MS);
1151 >            lock.writeLock().lock();
1152 >            assertFalse(lock.hasWaiters(c));
1153 >            assertEquals(0, lock.getWaitQueueLength(c));
1154 >            lock.writeLock().unlock();
1155 >            t.join(SHORT_DELAY_MS);
1156 >            assertFalse(t.isAlive());
1157 >        }
1158 >        catch (Exception ex) {
1159 >            unexpectedException();
1160 >        }
1161 >    }
1162 >
1163 >
1164 >    /**
1165 >     * getWaitingThreads returns only and all waiting threads
1166 >     */
1167 >    public void testGetWaitingThreads() {
1168 >        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();  
1169 >        final Condition c = lock.writeLock().newCondition();
1170 >        Thread t1 = new Thread(new Runnable() {
1171 >                public void run() {
1172 >                    try {
1173 >                        lock.writeLock().lock();
1174 >                        threadAssertTrue(lock.getWaitingThreads(c).isEmpty());
1175 >                        c.await();
1176 >                        lock.writeLock().unlock();
1177 >                    }
1178 >                    catch(InterruptedException e) {
1179 >                        threadUnexpectedException();
1180 >                    }
1181 >                }
1182 >            });
1183 >
1184 >        Thread t2 = new Thread(new Runnable() {
1185 >                public void run() {
1186 >                    try {
1187 >                        lock.writeLock().lock();
1188 >                        threadAssertFalse(lock.getWaitingThreads(c).isEmpty());
1189 >                        c.await();
1190 >                        lock.writeLock().unlock();
1191 >                    }
1192 >                    catch(InterruptedException e) {
1193 >                        threadUnexpectedException();
1194 >                    }
1195 >                }
1196 >            });
1197 >
1198 >        try {
1199 >            lock.writeLock().lock();
1200 >            assertTrue(lock.getWaitingThreads(c).isEmpty());
1201 >            lock.writeLock().unlock();
1202 >            t1.start();
1203 >            Thread.sleep(SHORT_DELAY_MS);
1204 >            t2.start();
1205 >            Thread.sleep(SHORT_DELAY_MS);
1206 >            lock.writeLock().lock();
1207 >            assertTrue(lock.hasWaiters(c));
1208 >            assertTrue(lock.getWaitingThreads(c).contains(t1));
1209 >            assertTrue(lock.getWaitingThreads(c).contains(t2));
1210 >            c.signalAll();
1211 >            lock.writeLock().unlock();
1212 >            Thread.sleep(SHORT_DELAY_MS);
1213 >            lock.writeLock().lock();
1214 >            assertFalse(lock.hasWaiters(c));
1215 >            assertTrue(lock.getWaitingThreads(c).isEmpty());
1216 >            lock.writeLock().unlock();
1217 >            t1.join(SHORT_DELAY_MS);
1218 >            t2.join(SHORT_DELAY_MS);
1219 >            assertFalse(t1.isAlive());
1220 >            assertFalse(t2.isAlive());
1221 >        }
1222 >        catch (Exception ex) {
1223 >            unexpectedException();
1224 >        }
1225      }
112    
1226  
1227   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines