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.16 by dl, Wed Jan 7 01:02:17 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 {
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());  
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 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 <    private static long SHORT_DELAY_MS = 100;
37 <    private static long MEDIUM_DELAY_MS = 1000;
38 <    private static long LONG_DELAY_MS = 10000;
39 <
29 <    /*
30 <     * Unlocks an unlocked lock, throws Illegal Monitor State
31 <     *
36 >
37 >    /**
38 >     * A runnable calling lockInterruptibly that expects to be
39 >     * interrupted
40       */
41 <    
42 <    public void testIllegalMonitorStateException(){
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 <        try{
71 <            rl.writeLock().unlock();
72 <            fail("Should of thown Illegal Monitor State Exception");
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 <        }catch(IllegalMonitorStateException success){}
79 >    /**
80 >     * write-locking and read-locking an unlocked lock succeed
81 >     */
82 >    public void testLock() {
83 >        ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
84 >        rl.writeLock().lock();
85 >        assertTrue(rl.isWriteLocked());
86 >        assertTrue(rl.isWriteLockedByCurrentThread());
87 >        assertEquals(0, rl.getReadLockCount());
88 >        rl.writeLock().unlock();
89 >        assertFalse(rl.isWriteLocked());
90 >        assertFalse(rl.isWriteLockedByCurrentThread());
91 >        assertEquals(0, rl.getReadLockCount());
92 >        rl.readLock().lock();
93 >        assertFalse(rl.isWriteLocked());
94 >        assertFalse(rl.isWriteLockedByCurrentThread());
95 >        assertEquals(1, rl.getReadLockCount());
96 >        rl.readLock().unlock();
97 >        assertFalse(rl.isWriteLocked());
98 >        assertFalse(rl.isWriteLockedByCurrentThread());
99 >        assertEquals(0, rl.getReadLockCount());
100      }
101  
102  
103 +    /**
104 +     * locking an unlocked fair lock succeeds
105 +     */
106 +    public void testFairLock() {
107 +        ReentrantReadWriteLock rl = new ReentrantReadWriteLock(true);
108 +        rl.writeLock().lock();
109 +        assertTrue(rl.isWriteLocked());
110 +        assertTrue(rl.isWriteLockedByCurrentThread());
111 +        assertEquals(0, rl.getReadLockCount());
112 +        rl.writeLock().unlock();
113 +        assertFalse(rl.isWriteLocked());
114 +        assertFalse(rl.isWriteLockedByCurrentThread());
115 +        assertEquals(0, rl.getReadLockCount());
116 +        rl.readLock().lock();
117 +        assertFalse(rl.isWriteLocked());
118 +        assertFalse(rl.isWriteLockedByCurrentThread());
119 +        assertEquals(1, rl.getReadLockCount());
120 +        rl.readLock().unlock();
121 +        assertFalse(rl.isWriteLocked());
122 +        assertFalse(rl.isWriteLockedByCurrentThread());
123 +        assertEquals(0, rl.getReadLockCount());
124 +    }
125 +
126 +    /**
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  
142 <    public void testInterruptedException(){
142 >    /**
143 >     * write-unlocking an unlocked lock throws IllegalMonitorStateException
144 >     */
145 >    public void testUnlock_IllegalMonitorStateException() {
146 >        ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
147 >        try {
148 >            rl.writeLock().unlock();
149 >            shouldThrow();
150 >        } catch(IllegalMonitorStateException success){}
151 >    }
152 >
153 >
154 >    /**
155 >     * write-lockInterruptibly is interruptible
156 >     */
157 >    public void testWriteLockInterruptibly_Interrupted() {
158          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
47        lock.writeLock().lock();
159          Thread t = new Thread(new Runnable() {
160 <                public void run(){
161 <                    try{
160 >                public void run() {
161 >                    try {
162 >                        lock.writeLock().lockInterruptibly();
163 >                        lock.writeLock().unlock();
164                          lock.writeLock().lockInterruptibly();
165 <                        fail("should throw");
166 <                    }catch(InterruptedException success){}
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 <            fail("unexpected exception");
176 >            unexpectedException();
177          }
178      }
179  
180 <    public void testInterruptedException2(){
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{
187 >                public void run() {
188 >                    try {
189                          lock.writeLock().tryLock(1000,TimeUnit.MILLISECONDS);
190 <                        fail("should throw");
191 <                    }catch(InterruptedException success){}
190 >                        threadShouldThrow();
191 >                    } catch(InterruptedException success){}
192                  }
193              });
194          try {
# Line 80 | Line 197 | public class ReentrantReadWriteLockTest
197              lock.writeLock().unlock();
198              t.join();
199          } catch(Exception e){
200 <            fail("unexpected exception");
200 >            unexpectedException();
201          }
202      }
203  
204 <    public void testInterruptedException3(){
204 >    /**
205 >     * read-lockInterruptibly is interruptible
206 >     */
207 >    public void testReadLockInterruptibly_Interrupted() {
208          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
209          lock.writeLock().lock();
210          Thread t = new Thread(new Runnable() {
211 <                public void run(){
212 <                    try{
211 >                public void run() {
212 >                    try {
213                          lock.readLock().lockInterruptibly();
214 <                        fail("should throw");
95 <                    }catch(InterruptedException success){}
214 >                    } catch(InterruptedException success){}
215                  }
216              });
217          try {
# Line 101 | Line 220 | public class ReentrantReadWriteLockTest
220              lock.writeLock().unlock();
221              t.join();
222          } catch(Exception e){
223 <            fail("unexpected exception");
223 >            unexpectedException();
224          }
225      }
226  
227 <    public void testInterruptedException4(){
227 >    /**
228 >     * timed read-tryLock is interruptible
229 >     */
230 >    public void testReadTryLock_Interrupted() {
231          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
232          lock.writeLock().lock();
233          Thread t = new Thread(new Runnable() {
234 <                public void run(){
235 <                    try{
234 >                public void run() {
235 >                    try {
236                          lock.readLock().tryLock(1000,TimeUnit.MILLISECONDS);
237 <                        fail("should throw");
238 <                    }catch(InterruptedException success){}
237 >                        threadShouldThrow();
238 >                    } catch(InterruptedException success){}
239                  }
240              });
241          try {
# Line 121 | Line 243 | public class ReentrantReadWriteLockTest
243              t.interrupt();
244              t.join();
245          } catch(Exception e){
246 <            fail("unexpected exception");
246 >            unexpectedException();
247          }
248      }
249  
250      
251 <    public void testTryLockWhenLocked() {
251 >    /**
252 >     * write-tryLock fails if locked
253 >     */
254 >    public void testWriteTryLockWhenLocked() {
255          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
256          lock.writeLock().lock();
257          Thread t = new Thread(new Runnable() {
258 <                public void run(){
259 <                    assertFalse(lock.writeLock().tryLock());
258 >                public void run() {
259 >                    threadAssertFalse(lock.writeLock().tryLock());
260                  }
261              });
262          try {
# Line 139 | Line 264 | public class ReentrantReadWriteLockTest
264              t.join();
265              lock.writeLock().unlock();
266          } catch(Exception e){
267 <            fail("unexpected exception");
267 >            unexpectedException();
268          }
269      }
270  
271 <    public void testTryLockWhenLocked2() {
271 >    /**
272 >     * read-tryLock fails if locked
273 >     */
274 >    public void testReadTryLockWhenLocked() {
275          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
276          lock.writeLock().lock();
277          Thread t = new Thread(new Runnable() {
278 <                public void run(){
279 <                    assertFalse(lock.readLock().tryLock());
278 >                public void run() {
279 >                    threadAssertFalse(lock.readLock().tryLock());
280                  }
281              });
282          try {
# Line 156 | Line 284 | public class ReentrantReadWriteLockTest
284              t.join();
285              lock.writeLock().unlock();
286          } catch(Exception e){
287 <            fail("unexpected exception");
287 >            unexpectedException();
288          }
289      }
290  
291 +    /**
292 +     * Multiple threads can hold a read lock when not write-locked
293 +     */
294      public void testMultipleReadLocks() {
295          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
296          lock.readLock().lock();
297          Thread t = new Thread(new Runnable() {
298 <                public void run(){
299 <                    assertTrue(lock.readLock().tryLock());
298 >                public void run() {
299 >                    threadAssertTrue(lock.readLock().tryLock());
300                      lock.readLock().unlock();
301                  }
302              });
# Line 174 | Line 305 | public class ReentrantReadWriteLockTest
305              t.join();
306              lock.readLock().unlock();
307          } catch(Exception e){
308 <            fail("unexpected exception");
308 >            unexpectedException();
309          }
310      }
311  
312 +    /**
313 +     * A writelock succeeds after reading threads unlock
314 +     */
315      public void testWriteAfterMultipleReadLocks() {
316          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
317          lock.readLock().lock();
318          Thread t1 = new Thread(new Runnable() {
319 <                public void run(){
319 >                public void run() {
320                      lock.readLock().lock();
321                      lock.readLock().unlock();
322                  }
323              });
324          Thread t2 = new Thread(new Runnable() {
325 <                public void run(){
325 >                public void run() {
326                      lock.writeLock().lock();
327                      lock.writeLock().unlock();
328                  }
# Line 205 | Line 339 | public class ReentrantReadWriteLockTest
339              assertTrue(!t2.isAlive());
340            
341          } catch(Exception e){
342 <            fail("unexpected exception");
342 >            unexpectedException();
343          }
344      }
345  
346 +    /**
347 +     * Readlocks succeed after a writing thread unlocks
348 +     */
349      public void testReadAfterWriteLock() {
350          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
351          lock.writeLock().lock();
352          Thread t1 = new Thread(new Runnable() {
353 <                public void run(){
353 >                public void run() {
354                      lock.readLock().lock();
355                      lock.readLock().unlock();
356                  }
357              });
358          Thread t2 = new Thread(new Runnable() {
359 <                public void run(){
359 >                public void run() {
360                      lock.readLock().lock();
361                      lock.readLock().unlock();
362                  }
# Line 236 | Line 373 | public class ReentrantReadWriteLockTest
373              assertTrue(!t2.isAlive());
374            
375          } catch(Exception e){
376 <            fail("unexpected exception");
376 >            unexpectedException();
377          }
378      }
379  
380  
381 +    /**
382 +     * Read tryLock succeeds if readlocked but not writelocked
383 +     */
384      public void testTryLockWhenReadLocked() {
385          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
386          lock.readLock().lock();
387          Thread t = new Thread(new Runnable() {
388 <                public void run(){
389 <                    assertTrue(lock.readLock().tryLock());
388 >                public void run() {
389 >                    threadAssertTrue(lock.readLock().tryLock());
390                      lock.readLock().unlock();
391                  }
392              });
# Line 255 | Line 395 | public class ReentrantReadWriteLockTest
395              t.join();
396              lock.readLock().unlock();
397          } catch(Exception e){
398 <            fail("unexpected exception");
398 >            unexpectedException();
399          }
400      }
401  
402      
403  
404 +    /**
405 +     * write tryLock fails when readlocked
406 +     */
407      public void testWriteTryLockWhenReadLocked() {
408          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
409          lock.readLock().lock();
410          Thread t = new Thread(new Runnable() {
411 <                public void run(){
412 <                    assertFalse(lock.writeLock().tryLock());
411 >                public void run() {
412 >                    threadAssertFalse(lock.writeLock().tryLock());
413                  }
414              });
415          try {
# Line 274 | Line 417 | public class ReentrantReadWriteLockTest
417              t.join();
418              lock.readLock().unlock();
419          } catch(Exception e){
420 <            fail("unexpected exception");
420 >            unexpectedException();
421          }
422      }
423  
424      
425  
426 <    public void testTryLock_Timeout(){
426 >    /**
427 >     * write timed tryLock times out if locked
428 >     */
429 >    public void testWriteTryLock_Timeout() {
430          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
431          lock.writeLock().lock();
432          Thread t = new Thread(new Runnable() {
433 <                public void run(){
433 >                public void run() {
434                      try {
435 <                        assertFalse(lock.writeLock().tryLock(1, TimeUnit.MILLISECONDS));
435 >                        threadAssertFalse(lock.writeLock().tryLock(1, TimeUnit.MILLISECONDS));
436                      } catch (Exception ex) {
437 <                        fail("unexpected exception");
437 >                        threadUnexpectedException();
438                      }
439                  }
440              });
# Line 297 | Line 443 | public class ReentrantReadWriteLockTest
443              t.join();
444              lock.writeLock().unlock();
445          } catch(Exception e){
446 <            fail("unexpected exception");
446 >            unexpectedException();
447          }
448      }
449  
450 <    public void testTryLock_Timeout2(){
450 >    /**
451 >     * read timed tryLock times out if write-locked
452 >     */
453 >    public void testReadTryLock_Timeout() {
454          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
455          lock.writeLock().lock();
456          Thread t = new Thread(new Runnable() {
457 <                public void run(){
457 >                public void run() {
458                      try {
459 <                        assertFalse(lock.readLock().tryLock(1, TimeUnit.MILLISECONDS));
459 >                        threadAssertFalse(lock.readLock().tryLock(1, TimeUnit.MILLISECONDS));
460                      } catch (Exception ex) {
461 <                        fail("unexpected exception");
461 >                        threadUnexpectedException();
462                      }
463                  }
464              });
# Line 318 | Line 467 | public class ReentrantReadWriteLockTest
467              t.join();
468              lock.writeLock().unlock();
469          } catch(Exception e){
470 <            fail("unexpected exception");
470 >            unexpectedException();
471          }
472      }
473  
474  
475 <    public void testLockInterruptibly() {
475 >    /**
476 >     * write lockInterruptibly succeeds if lock free else is interruptible
477 >     */
478 >    public void testWriteLockInterruptibly() {
479          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
480          try {
481              lock.writeLock().lockInterruptibly();
482          } catch(Exception e) {
483 <            fail("unexpected exception");
483 >            unexpectedException();
484          }
485          Thread t = new Thread(new Runnable() {
486                  public void run() {
487                      try {
488                          lock.writeLock().lockInterruptibly();
489 <                        fail("should throw");
489 >                        threadShouldThrow();
490                      }
491                      catch(InterruptedException success) {
492                      }
# Line 346 | Line 498 | public class ReentrantReadWriteLockTest
498              t.join();
499              lock.writeLock().unlock();
500          } catch(Exception e){
501 <            fail("unexpected exception");
501 >            unexpectedException();
502          }
503      }
504  
505 <    public void testLockInterruptibly2() {
505 >    /**
506 >     *  read lockInterruptibly succeeds if lock free else is interruptible
507 >     */
508 >    public void testReadLockInterruptibly() {
509          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
510          try {
511              lock.writeLock().lockInterruptibly();
512          } catch(Exception e) {
513 <            fail("unexpected exception");
513 >            unexpectedException();
514          }
515          Thread t = new Thread(new Runnable() {
516                  public void run() {
517                      try {
518                          lock.readLock().lockInterruptibly();
519 <                        fail("should throw");
519 >                        threadShouldThrow();
520                      }
521                      catch(InterruptedException success) {
522                      }
# Line 373 | Line 528 | public class ReentrantReadWriteLockTest
528              t.join();
529              lock.writeLock().unlock();
530          } catch(Exception e){
531 <            fail("unexpected exception");
531 >            unexpectedException();
532          }
533      }
534  
535 +    /**
536 +     * Calling await without holding lock throws IllegalMonitorStateException
537 +     */
538      public void testAwait_IllegalMonitor() {
539          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
540          final Condition c = lock.writeLock().newCondition();
541          try {
542              c.await();
543 <            fail("should throw");
543 >            shouldThrow();
544          }
545          catch (IllegalMonitorStateException success) {
546          }
547          catch (Exception ex) {
548 <            fail("should throw IMSE");
548 >            shouldThrow();
549          }
550      }
551  
552 +    /**
553 +     * Calling signal without holding lock throws IllegalMonitorStateException
554 +     */
555      public void testSignal_IllegalMonitor() {
556          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
557          final Condition c = lock.writeLock().newCondition();
558          try {
559              c.signal();
560 <            fail("should throw");
560 >            shouldThrow();
561          }
562          catch (IllegalMonitorStateException success) {
563          }
564          catch (Exception ex) {
565 <            fail("should throw IMSE");
565 >            unexpectedException();
566          }
567      }
568  
569 +    /**
570 +     * awaitNanos without a signal times out
571 +     */
572      public void testAwaitNanos_Timeout() {
573          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
574          final Condition c = lock.writeLock().newCondition();
# Line 415 | Line 579 | public class ReentrantReadWriteLockTest
579              lock.writeLock().unlock();
580          }
581          catch (Exception ex) {
582 <            fail("unexpected exception");
582 >            unexpectedException();
583          }
584      }
585  
586 +
587 +    /**
588 +     *  timed await without a signal times out
589 +     */
590      public void testAwait_Timeout() {
591          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
592          final Condition c = lock.writeLock().newCondition();
# Line 428 | Line 596 | public class ReentrantReadWriteLockTest
596              lock.writeLock().unlock();
597          }
598          catch (Exception ex) {
599 <            fail("unexpected exception");
599 >            unexpectedException();
600          }
601      }
602  
603 +    /**
604 +     * awaitUntil without a signal times out
605 +     */
606      public void testAwaitUntil_Timeout() {
607          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
608          final Condition c = lock.writeLock().newCondition();
# Line 442 | Line 613 | public class ReentrantReadWriteLockTest
613              lock.writeLock().unlock();
614          }
615          catch (Exception ex) {
616 <            fail("unexpected exception");
616 >            unexpectedException();
617          }
618      }
619  
620 +    /**
621 +     * await returns when signalled
622 +     */
623      public void testAwait() {
624          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
625          final Condition c = lock.writeLock().newCondition();
# Line 457 | Line 631 | public class ReentrantReadWriteLockTest
631                          lock.writeLock().unlock();
632                      }
633                      catch(InterruptedException e) {
634 <                        fail("unexpected exception");
634 >                        threadUnexpectedException();
635                      }
636                  }
637              });
# Line 472 | Line 646 | public class ReentrantReadWriteLockTest
646              assertFalse(t.isAlive());
647          }
648          catch (Exception ex) {
649 <            fail("unexpected exception");
649 >            unexpectedException();
650          }
651      }
652  
653 +    /**
654 +     * awaitUninterruptibly doesn't abort on interrupt
655 +     */
656      public void testAwaitUninterruptibly() {
657          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
658          final Condition c = lock.writeLock().newCondition();
# Line 494 | Line 671 | public class ReentrantReadWriteLockTest
671              lock.writeLock().lock();
672              c.signal();
673              lock.writeLock().unlock();
674 +            assert(t.isInterrupted());
675              t.join(SHORT_DELAY_MS);
676              assertFalse(t.isAlive());
677          }
678          catch (Exception ex) {
679 <            fail("unexpected exception");
679 >            unexpectedException();
680          }
681      }
682  
683 +    /**
684 +     * await is interruptible
685 +     */
686      public void testAwait_Interrupt() {
687          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
688          final Condition c = lock.writeLock().newCondition();
# Line 511 | Line 692 | public class ReentrantReadWriteLockTest
692                          lock.writeLock().lock();
693                          c.await();
694                          lock.writeLock().unlock();
695 <                        fail("should throw");
695 >                        threadShouldThrow();
696                      }
697                      catch(InterruptedException success) {
698                      }
# Line 526 | Line 707 | public class ReentrantReadWriteLockTest
707              assertFalse(t.isAlive());
708          }
709          catch (Exception ex) {
710 <            fail("unexpected exception");
710 >            unexpectedException();
711          }
712      }
713  
714 +    /**
715 +     * awaitNanos is interruptible
716 +     */
717      public void testAwaitNanos_Interrupt() {
718          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
719          final Condition c = lock.writeLock().newCondition();
# Line 539 | Line 723 | public class ReentrantReadWriteLockTest
723                          lock.writeLock().lock();
724                          c.awaitNanos(SHORT_DELAY_MS * 2 * 1000000);
725                          lock.writeLock().unlock();
726 <                        fail("should throw");
726 >                        threadShouldThrow();
727                      }
728                      catch(InterruptedException success) {
729                      }
# Line 554 | Line 738 | public class ReentrantReadWriteLockTest
738              assertFalse(t.isAlive());
739          }
740          catch (Exception ex) {
741 <            fail("unexpected exception");
741 >            unexpectedException();
742          }
743      }
744  
745 +    /**
746 +     * awaitUntil is interruptible
747 +     */
748      public void testAwaitUntil_Interrupt() {
749          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
750          final Condition c = lock.writeLock().newCondition();
# Line 568 | Line 755 | public class ReentrantReadWriteLockTest
755                          java.util.Date d = new java.util.Date();
756                          c.awaitUntil(new java.util.Date(d.getTime() + 10000));
757                          lock.writeLock().unlock();
758 <                        fail("should throw");
758 >                        threadShouldThrow();
759                      }
760                      catch(InterruptedException success) {
761                      }
# Line 583 | Line 770 | public class ReentrantReadWriteLockTest
770              assertFalse(t.isAlive());
771          }
772          catch (Exception ex) {
773 <            fail("unexpected exception");
773 >            unexpectedException();
774          }
775      }
776  
777 +    /**
778 +     * signalAll wakes up all threads
779 +     */
780      public void testSignalAll() {
781          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
782          final Condition c = lock.writeLock().newCondition();
# Line 598 | Line 788 | public class ReentrantReadWriteLockTest
788                          lock.writeLock().unlock();
789                      }
790                      catch(InterruptedException e) {
791 <                        fail("unexpected exception");
791 >                        threadUnexpectedException();
792                      }
793                  }
794              });
# Line 611 | Line 801 | public class ReentrantReadWriteLockTest
801                          lock.writeLock().unlock();
802                      }
803                      catch(InterruptedException e) {
804 <                        fail("unexpected exception");
804 >                        threadUnexpectedException();
805                      }
806                  }
807              });
# Line 629 | Line 819 | public class ReentrantReadWriteLockTest
819              assertFalse(t2.isAlive());
820          }
821          catch (Exception ex) {
822 <            fail("unexpected exception");
822 >            unexpectedException();
823          }
824      }
825  
826 +    /**
827 +     * A serialized lock deserializes as unlocked
828 +     */
829      public void testSerialization() {
830          ReentrantReadWriteLock l = new ReentrantReadWriteLock();
831          l.readLock().lock();
# Line 651 | Line 844 | public class ReentrantReadWriteLockTest
844              r.readLock().unlock();
845          } catch(Exception e){
846              e.printStackTrace();
847 <            fail("unexpected exception");
847 >            unexpectedException();
848 >        }
849 >    }
850 >
851 >    /**
852 >     * hasQueuedThreads reports whether there are waiting threads
853 >     */
854 >    public void testhasQueuedThreads() {
855 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
856 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
857 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
858 >        try {
859 >            assertFalse(lock.hasQueuedThreads());
860 >            lock.writeLock().lock();
861 >            t1.start();
862 >            Thread.sleep(SHORT_DELAY_MS);
863 >            assertTrue(lock.hasQueuedThreads());
864 >            t2.start();
865 >            Thread.sleep(SHORT_DELAY_MS);
866 >            assertTrue(lock.hasQueuedThreads());
867 >            t1.interrupt();
868 >            Thread.sleep(SHORT_DELAY_MS);
869 >            assertTrue(lock.hasQueuedThreads());
870 >            lock.writeLock().unlock();
871 >            Thread.sleep(SHORT_DELAY_MS);
872 >            assertFalse(lock.hasQueuedThreads());
873 >            t1.join();
874 >            t2.join();
875 >        } catch(Exception e){
876 >            unexpectedException();
877 >        }
878 >    }
879 >
880 >    /**
881 >     * getQueueLength reports number of waiting threads
882 >     */
883 >    public void testGetQueueLength() {
884 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
885 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
886 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
887 >        try {
888 >            assertEquals(0, lock.getQueueLength());
889 >            lock.writeLock().lock();
890 >            t1.start();
891 >            Thread.sleep(SHORT_DELAY_MS);
892 >            assertEquals(1, lock.getQueueLength());
893 >            t2.start();
894 >            Thread.sleep(SHORT_DELAY_MS);
895 >            assertEquals(2, lock.getQueueLength());
896 >            t1.interrupt();
897 >            Thread.sleep(SHORT_DELAY_MS);
898 >            assertEquals(1, lock.getQueueLength());
899 >            lock.writeLock().unlock();
900 >            Thread.sleep(SHORT_DELAY_MS);
901 >            assertEquals(0, lock.getQueueLength());
902 >            t1.join();
903 >            t2.join();
904 >        } catch(Exception e){
905 >            unexpectedException();
906 >        }
907 >    }
908 >
909 >    /**
910 >     * getQueuedThreads includes waiting threads
911 >     */
912 >    public void testGetQueuedThreads() {
913 >        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
914 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
915 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
916 >        try {
917 >            assertTrue(lock.getQueuedThreads().isEmpty());
918 >            lock.writeLock().lock();
919 >            assertTrue(lock.getQueuedThreads().isEmpty());
920 >            t1.start();
921 >            Thread.sleep(SHORT_DELAY_MS);
922 >            assertTrue(lock.getQueuedThreads().contains(t1));
923 >            t2.start();
924 >            Thread.sleep(SHORT_DELAY_MS);
925 >            assertTrue(lock.getQueuedThreads().contains(t1));
926 >            assertTrue(lock.getQueuedThreads().contains(t2));
927 >            t1.interrupt();
928 >            Thread.sleep(SHORT_DELAY_MS);
929 >            assertFalse(lock.getQueuedThreads().contains(t1));
930 >            assertTrue(lock.getQueuedThreads().contains(t2));
931 >            lock.writeLock().unlock();
932 >            Thread.sleep(SHORT_DELAY_MS);
933 >            assertTrue(lock.getQueuedThreads().isEmpty());
934 >            t1.join();
935 >            t2.join();
936 >        } catch(Exception e){
937 >            unexpectedException();
938 >        }
939 >    }
940 >
941 >    /**
942 >     * hasWaiters throws NPE if null
943 >     */
944 >    public void testHasWaitersNPE() {
945 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
946 >        try {
947 >            lock.hasWaiters(null);
948 >            shouldThrow();
949 >        } catch (NullPointerException success) {
950 >        } catch (Exception ex) {
951 >            unexpectedException();
952 >        }
953 >    }
954 >
955 >    /**
956 >     * getWaitQueueLength throws NPE if null
957 >     */
958 >    public void testGetWaitQueueLengthNPE() {
959 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
960 >        try {
961 >            lock.getWaitQueueLength(null);
962 >            shouldThrow();
963 >        } catch (NullPointerException success) {
964 >        } catch (Exception ex) {
965 >            unexpectedException();
966 >        }
967 >    }
968 >
969 >
970 >    /**
971 >     * getWaitingThreads throws NPE if null
972 >     */
973 >    public void testGetWaitingThreadsNPE() {
974 >        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
975 >        try {
976 >            lock.getWaitingThreads(null);
977 >            shouldThrow();
978 >        } catch (NullPointerException success) {
979 >        } catch (Exception ex) {
980 >            unexpectedException();
981          }
982      }
983  
984 +    /**
985 +     * hasWaiters throws IAE if not owned
986 +     */
987 +    public void testHasWaitersIAE() {
988 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
989 +        final Condition c = (lock.writeLock().newCondition());
990 +        final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock();
991 +        try {
992 +            lock2.hasWaiters(c);
993 +            shouldThrow();
994 +        } catch (IllegalArgumentException success) {
995 +        } catch (Exception ex) {
996 +            unexpectedException();
997 +        }
998 +    }
999 +
1000 +    /**
1001 +     * hasWaiters throws IMSE if not locked
1002 +     */
1003 +    public void testHasWaitersIMSE() {
1004 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1005 +        final Condition c = (lock.writeLock().newCondition());
1006 +        try {
1007 +            lock.hasWaiters(c);
1008 +            shouldThrow();
1009 +        } catch (IllegalMonitorStateException success) {
1010 +        } catch (Exception ex) {
1011 +            unexpectedException();
1012 +        }
1013 +    }
1014 +
1015 +
1016 +    /**
1017 +     * getWaitQueueLength throws IAE if not owned
1018 +     */
1019 +    public void testGetWaitQueueLengthIAE() {
1020 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1021 +        final Condition c = (lock.writeLock().newCondition());
1022 +        final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock();
1023 +        try {
1024 +            lock2.getWaitQueueLength(c);
1025 +            shouldThrow();
1026 +        } catch (IllegalArgumentException success) {
1027 +        } catch (Exception ex) {
1028 +            unexpectedException();
1029 +        }
1030 +    }
1031 +
1032 +    /**
1033 +     * getWaitQueueLength throws IMSE if not locked
1034 +     */
1035 +    public void testGetWaitQueueLengthIMSE() {
1036 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1037 +        final Condition c = (lock.writeLock().newCondition());
1038 +        try {
1039 +            lock.getWaitQueueLength(c);
1040 +            shouldThrow();
1041 +        } catch (IllegalMonitorStateException success) {
1042 +        } catch (Exception ex) {
1043 +            unexpectedException();
1044 +        }
1045 +    }
1046 +
1047 +
1048 +    /**
1049 +     * getWaitingThreads throws IAE if not owned
1050 +     */
1051 +    public void testGetWaitingThreadsIAE() {
1052 +        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();  
1053 +        final Condition c = (lock.writeLock().newCondition());
1054 +        final PublicReentrantReadWriteLock lock2 = new PublicReentrantReadWriteLock();  
1055 +        try {
1056 +            lock2.getWaitingThreads(c);
1057 +            shouldThrow();
1058 +        } catch (IllegalArgumentException success) {
1059 +        } catch (Exception ex) {
1060 +            unexpectedException();
1061 +        }
1062 +    }
1063 +
1064 +    /**
1065 +     * getWaitingThreads throws IMSE if not locked
1066 +     */
1067 +    public void testGetWaitingThreadsIMSE() {
1068 +        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();  
1069 +        final Condition c = (lock.writeLock().newCondition());
1070 +        try {
1071 +            lock.getWaitingThreads(c);
1072 +            shouldThrow();
1073 +        } catch (IllegalMonitorStateException success) {
1074 +        } catch (Exception ex) {
1075 +            unexpectedException();
1076 +        }
1077 +    }
1078 +
1079 +
1080 +    /**
1081 +     * hasWaiters returns true when a thread is waiting, else false
1082 +     */
1083 +    public void testHasWaiters() {
1084 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1085 +        final Condition c = (lock.writeLock().newCondition());
1086 +        Thread t = new Thread(new Runnable() {
1087 +                public void run() {
1088 +                    try {
1089 +                        lock.writeLock().lock();
1090 +                        threadAssertFalse(lock.hasWaiters(c));
1091 +                        threadAssertEquals(0, lock.getWaitQueueLength(c));
1092 +                        c.await();
1093 +                        lock.writeLock().unlock();
1094 +                    }
1095 +                    catch(InterruptedException e) {
1096 +                        threadUnexpectedException();
1097 +                    }
1098 +                }
1099 +            });
1100 +
1101 +        try {
1102 +            t.start();
1103 +            Thread.sleep(SHORT_DELAY_MS);
1104 +            lock.writeLock().lock();
1105 +            assertTrue(lock.hasWaiters(c));
1106 +            assertEquals(1, lock.getWaitQueueLength(c));
1107 +            c.signal();
1108 +            lock.writeLock().unlock();
1109 +            Thread.sleep(SHORT_DELAY_MS);
1110 +            lock.writeLock().lock();
1111 +            assertFalse(lock.hasWaiters(c));
1112 +            assertEquals(0, lock.getWaitQueueLength(c));
1113 +            lock.writeLock().unlock();
1114 +            t.join(SHORT_DELAY_MS);
1115 +            assertFalse(t.isAlive());
1116 +        }
1117 +        catch (Exception ex) {
1118 +            unexpectedException();
1119 +        }
1120 +    }
1121 +
1122 +    /**
1123 +     * getWaitQueueLength returns number of waiting threads
1124 +     */
1125 +    public void testGetWaitQueueLength() {
1126 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1127 +        final Condition c = (lock.writeLock().newCondition());
1128 +        Thread t = new Thread(new Runnable() {
1129 +                public void run() {
1130 +                    try {
1131 +                        lock.writeLock().lock();
1132 +                        threadAssertFalse(lock.hasWaiters(c));
1133 +                        threadAssertEquals(0, lock.getWaitQueueLength(c));
1134 +                        c.await();
1135 +                        lock.writeLock().unlock();
1136 +                    }
1137 +                    catch(InterruptedException e) {
1138 +                        threadUnexpectedException();
1139 +                    }
1140 +                }
1141 +            });
1142 +
1143 +        try {
1144 +            t.start();
1145 +            Thread.sleep(SHORT_DELAY_MS);
1146 +            lock.writeLock().lock();
1147 +            assertTrue(lock.hasWaiters(c));
1148 +            assertEquals(1, lock.getWaitQueueLength(c));
1149 +            c.signal();
1150 +            lock.writeLock().unlock();
1151 +            Thread.sleep(SHORT_DELAY_MS);
1152 +            lock.writeLock().lock();
1153 +            assertFalse(lock.hasWaiters(c));
1154 +            assertEquals(0, lock.getWaitQueueLength(c));
1155 +            lock.writeLock().unlock();
1156 +            t.join(SHORT_DELAY_MS);
1157 +            assertFalse(t.isAlive());
1158 +        }
1159 +        catch (Exception ex) {
1160 +            unexpectedException();
1161 +        }
1162 +    }
1163 +
1164 +
1165 +    /**
1166 +     * getWaitingThreads returns only and all waiting threads
1167 +     */
1168 +    public void testGetWaitingThreads() {
1169 +        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();  
1170 +        final Condition c = lock.writeLock().newCondition();
1171 +        Thread t1 = new Thread(new Runnable() {
1172 +                public void run() {
1173 +                    try {
1174 +                        lock.writeLock().lock();
1175 +                        threadAssertTrue(lock.getWaitingThreads(c).isEmpty());
1176 +                        c.await();
1177 +                        lock.writeLock().unlock();
1178 +                    }
1179 +                    catch(InterruptedException e) {
1180 +                        threadUnexpectedException();
1181 +                    }
1182 +                }
1183 +            });
1184 +
1185 +        Thread t2 = new Thread(new Runnable() {
1186 +                public void run() {
1187 +                    try {
1188 +                        lock.writeLock().lock();
1189 +                        threadAssertFalse(lock.getWaitingThreads(c).isEmpty());
1190 +                        c.await();
1191 +                        lock.writeLock().unlock();
1192 +                    }
1193 +                    catch(InterruptedException e) {
1194 +                        threadUnexpectedException();
1195 +                    }
1196 +                }
1197 +            });
1198 +
1199 +        try {
1200 +            lock.writeLock().lock();
1201 +            assertTrue(lock.getWaitingThreads(c).isEmpty());
1202 +            lock.writeLock().unlock();
1203 +            t1.start();
1204 +            Thread.sleep(SHORT_DELAY_MS);
1205 +            t2.start();
1206 +            Thread.sleep(SHORT_DELAY_MS);
1207 +            lock.writeLock().lock();
1208 +            assertTrue(lock.hasWaiters(c));
1209 +            assertTrue(lock.getWaitingThreads(c).contains(t1));
1210 +            assertTrue(lock.getWaitingThreads(c).contains(t2));
1211 +            c.signalAll();
1212 +            lock.writeLock().unlock();
1213 +            Thread.sleep(SHORT_DELAY_MS);
1214 +            lock.writeLock().lock();
1215 +            assertFalse(lock.hasWaiters(c));
1216 +            assertTrue(lock.getWaitingThreads(c).isEmpty());
1217 +            lock.writeLock().unlock();
1218 +            t1.join(SHORT_DELAY_MS);
1219 +            t2.join(SHORT_DELAY_MS);
1220 +            assertFalse(t1.isAlive());
1221 +            assertFalse(t2.isAlive());
1222 +        }
1223 +        catch (Exception ex) {
1224 +            unexpectedException();
1225 +        }
1226 +    }
1227  
1228   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines