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.9 by dl, Mon Dec 22 00:48:56 2003 UTC

# Line 9 | Line 9 | import junit.framework.*;
9   import java.util.concurrent.locks.*;
10   import java.util.concurrent.*;
11   import java.io.*;
12 + import java.util.*;
13  
14 < public class ReentrantReadWriteLockTest extends TestCase {
14 <    static int HOLD_COUNT_TEST_LIMIT = 20;
15 <    
14 > public class ReentrantReadWriteLockTest extends JSR166TestCase {
15      public static void main(String[] args) {
16          junit.textui.TestRunner.run (suite());  
17      }
19    
18      public static Test suite() {
19          return new TestSuite(ReentrantReadWriteLockTest.class);
20      }
21  
22 +    /**
23 +     * A runnable calling lockInterruptibly
24 +     */
25 +    class InterruptibleLockRunnable implements Runnable {
26 +        final ReentrantReadWriteLock lock;
27 +        InterruptibleLockRunnable(ReentrantReadWriteLock l) { lock = l; }
28 +        public void run() {
29 +            try {
30 +                lock.writeLock().lockInterruptibly();
31 +            } catch(InterruptedException success){}
32 +        }
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;
28 <
29 <    /*
30 <     * Unlocks an unlocked lock, throws Illegal Monitor State
31 <     *
36 >    /**
37 >     * A runnable calling lockInterruptibly that expects to be
38 >     * interrupted
39       */
40 <    
41 <    public void testIllegalMonitorStateException(){
40 >    class InterruptedLockRunnable implements Runnable {
41 >        final ReentrantReadWriteLock lock;
42 >        InterruptedLockRunnable(ReentrantReadWriteLock l) { lock = l; }
43 >        public void run() {
44 >            try {
45 >                lock.writeLock().lockInterruptibly();
46 >                threadShouldThrow();
47 >            } catch(InterruptedException success){}
48 >        }
49 >    }
50 >
51 >    /**
52 >     * Subclass to expose protected methods
53 >     */
54 >    static class PublicReentrantReadWriteLock extends ReentrantReadWriteLock {
55 >        PublicReentrantReadWriteLock() { super(); }
56 >        public Collection<Thread> getQueuedThreads() {
57 >            return super.getQueuedThreads();
58 >        }
59 >        public PublicCondition newCondition() {
60 >            return new PublicCondition(this);
61 >        }
62 >
63 >        static class PublicCondition extends ReentrantReadWriteLock.WriterConditionObject {
64 >            PublicCondition(PublicReentrantReadWriteLock l) { super(l); }
65 >            public Collection<Thread> getWaitingThreads() {
66 >                return super.getWaitingThreads();
67 >            }
68 >        }
69 >
70 >    }
71 >
72 >    /**
73 >     * Constructor sets given fairness, and is in unlocked state
74 >     */
75 >    public void testConstructor() {
76          ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
77 <        try{
78 <            rl.writeLock().unlock();
79 <            fail("Should of thown Illegal Monitor State Exception");
77 >        assertFalse(rl.isFair());
78 >        assertFalse(rl.isWriteLocked());
79 >        assertEquals(0, rl.getReadLockCount());
80 >        ReentrantReadWriteLock r2 = new ReentrantReadWriteLock(true);
81 >        assertTrue(r2.isFair());
82 >        assertFalse(r2.isWriteLocked());
83 >        assertEquals(0, r2.getReadLockCount());
84 >    }
85 >
86 >    /**
87 >     * write-locking and read-locking an unlocked lock succeed
88 >     */
89 >    public void testLock() {
90 >        ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
91 >        rl.writeLock().lock();
92 >        assertTrue(rl.isWriteLocked());
93 >        assertTrue(rl.isWriteLockedByCurrentThread());
94 >        assertEquals(0, rl.getReadLockCount());
95 >        rl.writeLock().unlock();
96 >        assertFalse(rl.isWriteLocked());
97 >        assertFalse(rl.isWriteLockedByCurrentThread());
98 >        assertEquals(0, rl.getReadLockCount());
99 >        rl.readLock().lock();
100 >        assertFalse(rl.isWriteLocked());
101 >        assertFalse(rl.isWriteLockedByCurrentThread());
102 >        assertEquals(1, rl.getReadLockCount());
103 >        rl.readLock().unlock();
104 >        assertFalse(rl.isWriteLocked());
105 >        assertFalse(rl.isWriteLockedByCurrentThread());
106 >        assertEquals(0, rl.getReadLockCount());
107 >    }
108 >
109 >
110 >    /**
111 >     * locking an unlocked fair lock succeeds
112 >     */
113 >    public void testFairLock() {
114 >        ReentrantReadWriteLock rl = new ReentrantReadWriteLock(true);
115 >        rl.writeLock().lock();
116 >        assertTrue(rl.isWriteLocked());
117 >        assertTrue(rl.isWriteLockedByCurrentThread());
118 >        assertEquals(0, rl.getReadLockCount());
119 >        rl.writeLock().unlock();
120 >        assertFalse(rl.isWriteLocked());
121 >        assertFalse(rl.isWriteLockedByCurrentThread());
122 >        assertEquals(0, rl.getReadLockCount());
123 >        rl.readLock().lock();
124 >        assertFalse(rl.isWriteLocked());
125 >        assertFalse(rl.isWriteLockedByCurrentThread());
126 >        assertEquals(1, rl.getReadLockCount());
127 >        rl.readLock().unlock();
128 >        assertFalse(rl.isWriteLocked());
129 >        assertFalse(rl.isWriteLockedByCurrentThread());
130 >        assertEquals(0, rl.getReadLockCount());
131 >    }
132  
133 <        }catch(IllegalMonitorStateException success){}
133 >    /**
134 >     * getWriteHoldCount returns number of recursive holds
135 >     */
136 >    public void testGetHoldCount() {
137 >        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
138 >        for(int i = 1; i <= SIZE; i++) {
139 >            lock.writeLock().lock();
140 >            assertEquals(i,lock.getWriteHoldCount());
141 >        }
142 >        for(int i = SIZE; i > 0; i--) {
143 >            lock.writeLock().unlock();
144 >            assertEquals(i-1,lock.getWriteHoldCount());
145 >        }
146      }
147 +    
148  
149 +    /**
150 +     * write-unlocking an unlocked lock throws IllegalMonitorStateException
151 +     */
152 +    public void testUnlock_IllegalMonitorStateException() {
153 +        ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
154 +        try {
155 +            rl.writeLock().unlock();
156 +            shouldThrow();
157 +        } catch(IllegalMonitorStateException success){}
158 +    }
159  
160  
161 <    public void testInterruptedException(){
161 >    /**
162 >     * write-lockInterruptibly is interruptible
163 >     */
164 >    public void testWriteLockInterruptibly_Interrupted() {
165          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
166          lock.writeLock().lock();
167          Thread t = new Thread(new Runnable() {
168 <                public void run(){
169 <                    try{
168 >                public void run() {
169 >                    try {
170                          lock.writeLock().lockInterruptibly();
171 <                        fail("should throw");
172 <                    }catch(InterruptedException success){}
171 >                        threadShouldThrow();
172 >                    } catch(InterruptedException success){}
173                  }
174              });
175          try {
# Line 59 | Line 178 | public class ReentrantReadWriteLockTest
178              lock.writeLock().unlock();
179              t.join();
180          } catch(Exception e){
181 <            fail("unexpected exception");
181 >            unexpectedException();
182          }
183      }
184  
185 <    public void testInterruptedException2(){
185 >    /**
186 >     * timed write-trylock is interruptible
187 >     */
188 >    public void testWriteTryLock_Interrupted() {
189          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
190          lock.writeLock().lock();
191          Thread t = new Thread(new Runnable() {
192 <                public void run(){
193 <                    try{
192 >                public void run() {
193 >                    try {
194                          lock.writeLock().tryLock(1000,TimeUnit.MILLISECONDS);
195 <                        fail("should throw");
196 <                    }catch(InterruptedException success){}
195 >                        threadShouldThrow();
196 >                    } catch(InterruptedException success){}
197                  }
198              });
199          try {
# Line 80 | Line 202 | public class ReentrantReadWriteLockTest
202              lock.writeLock().unlock();
203              t.join();
204          } catch(Exception e){
205 <            fail("unexpected exception");
205 >            unexpectedException();
206          }
207      }
208  
209 <    public void testInterruptedException3(){
209 >    /**
210 >     * read-lockInterruptibly is interruptible
211 >     */
212 >    public void testReadLockInterruptibly_Interrupted() {
213          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
214          lock.writeLock().lock();
215          Thread t = new Thread(new Runnable() {
216 <                public void run(){
217 <                    try{
216 >                public void run() {
217 >                    try {
218                          lock.readLock().lockInterruptibly();
219 <                        fail("should throw");
220 <                    }catch(InterruptedException success){}
219 >                        threadShouldThrow();
220 >                    } catch(InterruptedException success){}
221                  }
222              });
223          try {
# Line 101 | Line 226 | public class ReentrantReadWriteLockTest
226              lock.writeLock().unlock();
227              t.join();
228          } catch(Exception e){
229 <            fail("unexpected exception");
229 >            unexpectedException();
230          }
231      }
232  
233 <    public void testInterruptedException4(){
233 >    /**
234 >     * timed read-trylock is interruptible
235 >     */
236 >    public void testReadTryLock_Interrupted() {
237          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
238          lock.writeLock().lock();
239          Thread t = new Thread(new Runnable() {
240 <                public void run(){
241 <                    try{
240 >                public void run() {
241 >                    try {
242                          lock.readLock().tryLock(1000,TimeUnit.MILLISECONDS);
243 <                        fail("should throw");
244 <                    }catch(InterruptedException success){}
243 >                        threadShouldThrow();
244 >                    } catch(InterruptedException success){}
245                  }
246              });
247          try {
# Line 121 | Line 249 | public class ReentrantReadWriteLockTest
249              t.interrupt();
250              t.join();
251          } catch(Exception e){
252 <            fail("unexpected exception");
252 >            unexpectedException();
253          }
254      }
255  
256      
257 <    public void testTryLockWhenLocked() {
257 >    /**
258 >     * write-trylock fails if locked
259 >     */
260 >    public void testWriteTryLockWhenLocked() {
261          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
262          lock.writeLock().lock();
263          Thread t = new Thread(new Runnable() {
264 <                public void run(){
265 <                    assertFalse(lock.writeLock().tryLock());
264 >                public void run() {
265 >                    threadAssertFalse(lock.writeLock().tryLock());
266                  }
267              });
268          try {
# Line 139 | Line 270 | public class ReentrantReadWriteLockTest
270              t.join();
271              lock.writeLock().unlock();
272          } catch(Exception e){
273 <            fail("unexpected exception");
273 >            unexpectedException();
274          }
275      }
276  
277 <    public void testTryLockWhenLocked2() {
277 >    /**
278 >     * read-trylock fails if locked
279 >     */
280 >    public void testReadTryLockWhenLocked() {
281          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
282          lock.writeLock().lock();
283          Thread t = new Thread(new Runnable() {
284 <                public void run(){
285 <                    assertFalse(lock.readLock().tryLock());
284 >                public void run() {
285 >                    threadAssertFalse(lock.readLock().tryLock());
286                  }
287              });
288          try {
# Line 156 | Line 290 | public class ReentrantReadWriteLockTest
290              t.join();
291              lock.writeLock().unlock();
292          } catch(Exception e){
293 <            fail("unexpected exception");
293 >            unexpectedException();
294          }
295      }
296  
297 +    /**
298 +     * Multiple threads can hold a read lock when not write-locked
299 +     */
300      public void testMultipleReadLocks() {
301          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
302          lock.readLock().lock();
303          Thread t = new Thread(new Runnable() {
304 <                public void run(){
305 <                    assertTrue(lock.readLock().tryLock());
304 >                public void run() {
305 >                    threadAssertTrue(lock.readLock().tryLock());
306                      lock.readLock().unlock();
307                  }
308              });
# Line 174 | Line 311 | public class ReentrantReadWriteLockTest
311              t.join();
312              lock.readLock().unlock();
313          } catch(Exception e){
314 <            fail("unexpected exception");
314 >            unexpectedException();
315          }
316      }
317  
318 +    /**
319 +     * A writelock succeeds after reading threads unlock
320 +     */
321      public void testWriteAfterMultipleReadLocks() {
322          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
323          lock.readLock().lock();
324          Thread t1 = new Thread(new Runnable() {
325 <                public void run(){
325 >                public void run() {
326                      lock.readLock().lock();
327                      lock.readLock().unlock();
328                  }
329              });
330          Thread t2 = new Thread(new Runnable() {
331 <                public void run(){
331 >                public void run() {
332                      lock.writeLock().lock();
333                      lock.writeLock().unlock();
334                  }
# Line 205 | Line 345 | public class ReentrantReadWriteLockTest
345              assertTrue(!t2.isAlive());
346            
347          } catch(Exception e){
348 <            fail("unexpected exception");
348 >            unexpectedException();
349          }
350      }
351  
352 +    /**
353 +     * Readlocks succeed after a writing thread unlocks
354 +     */
355      public void testReadAfterWriteLock() {
356          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
357          lock.writeLock().lock();
358          Thread t1 = new Thread(new Runnable() {
359 <                public void run(){
359 >                public void run() {
360                      lock.readLock().lock();
361                      lock.readLock().unlock();
362                  }
363              });
364          Thread t2 = new Thread(new Runnable() {
365 <                public void run(){
365 >                public void run() {
366                      lock.readLock().lock();
367                      lock.readLock().unlock();
368                  }
# Line 236 | Line 379 | public class ReentrantReadWriteLockTest
379              assertTrue(!t2.isAlive());
380            
381          } catch(Exception e){
382 <            fail("unexpected exception");
382 >            unexpectedException();
383          }
384      }
385  
386  
387 +    /**
388 +     * Read trylock succeeds if readlocked but not writelocked
389 +     */
390      public void testTryLockWhenReadLocked() {
391          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
392          lock.readLock().lock();
393          Thread t = new Thread(new Runnable() {
394 <                public void run(){
395 <                    assertTrue(lock.readLock().tryLock());
394 >                public void run() {
395 >                    threadAssertTrue(lock.readLock().tryLock());
396                      lock.readLock().unlock();
397                  }
398              });
# Line 255 | Line 401 | public class ReentrantReadWriteLockTest
401              t.join();
402              lock.readLock().unlock();
403          } catch(Exception e){
404 <            fail("unexpected exception");
404 >            unexpectedException();
405          }
406      }
407  
408      
409  
410 +    /**
411 +     * write trylock fails when readlocked
412 +     */
413      public void testWriteTryLockWhenReadLocked() {
414          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
415          lock.readLock().lock();
416          Thread t = new Thread(new Runnable() {
417 <                public void run(){
418 <                    assertFalse(lock.writeLock().tryLock());
417 >                public void run() {
418 >                    threadAssertFalse(lock.writeLock().tryLock());
419                  }
420              });
421          try {
# Line 274 | Line 423 | public class ReentrantReadWriteLockTest
423              t.join();
424              lock.readLock().unlock();
425          } catch(Exception e){
426 <            fail("unexpected exception");
426 >            unexpectedException();
427          }
428      }
429  
430      
431  
432 <    public void testTryLock_Timeout(){
432 >    /**
433 >     * write timed trylock times out if locked
434 >     */
435 >    public void testWriteTryLock_Timeout() {
436          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
437          lock.writeLock().lock();
438          Thread t = new Thread(new Runnable() {
439 <                public void run(){
439 >                public void run() {
440                      try {
441 <                        assertFalse(lock.writeLock().tryLock(1, TimeUnit.MILLISECONDS));
441 >                        threadAssertFalse(lock.writeLock().tryLock(1, TimeUnit.MILLISECONDS));
442                      } catch (Exception ex) {
443 <                        fail("unexpected exception");
443 >                        threadUnexpectedException();
444                      }
445                  }
446              });
# Line 297 | Line 449 | public class ReentrantReadWriteLockTest
449              t.join();
450              lock.writeLock().unlock();
451          } catch(Exception e){
452 <            fail("unexpected exception");
452 >            unexpectedException();
453          }
454      }
455  
456 <    public void testTryLock_Timeout2(){
456 >    /**
457 >     * read timed trylock times out if write-locked
458 >     */
459 >    public void testReadTryLock_Timeout() {
460          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
461          lock.writeLock().lock();
462          Thread t = new Thread(new Runnable() {
463 <                public void run(){
463 >                public void run() {
464                      try {
465 <                        assertFalse(lock.readLock().tryLock(1, TimeUnit.MILLISECONDS));
465 >                        threadAssertFalse(lock.readLock().tryLock(1, TimeUnit.MILLISECONDS));
466                      } catch (Exception ex) {
467 <                        fail("unexpected exception");
467 >                        threadUnexpectedException();
468                      }
469                  }
470              });
# Line 318 | Line 473 | public class ReentrantReadWriteLockTest
473              t.join();
474              lock.writeLock().unlock();
475          } catch(Exception e){
476 <            fail("unexpected exception");
476 >            unexpectedException();
477          }
478      }
479  
480  
481 <    public void testLockInterruptibly() {
481 >    /**
482 >     * write lockInterruptibly succeeds if lock free else is interruptible
483 >     */
484 >    public void testWriteLockInterruptibly() {
485          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
486          try {
487              lock.writeLock().lockInterruptibly();
488          } catch(Exception e) {
489 <            fail("unexpected exception");
489 >            unexpectedException();
490          }
491          Thread t = new Thread(new Runnable() {
492                  public void run() {
493                      try {
494                          lock.writeLock().lockInterruptibly();
495 <                        fail("should throw");
495 >                        threadShouldThrow();
496                      }
497                      catch(InterruptedException success) {
498                      }
# Line 346 | Line 504 | public class ReentrantReadWriteLockTest
504              t.join();
505              lock.writeLock().unlock();
506          } catch(Exception e){
507 <            fail("unexpected exception");
507 >            unexpectedException();
508          }
509      }
510  
511 <    public void testLockInterruptibly2() {
511 >    /**
512 >     *  read lockInterruptibly succeeds if lock free else is interruptible
513 >     */
514 >    public void testReadLockInterruptibly() {
515          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
516          try {
517              lock.writeLock().lockInterruptibly();
518          } catch(Exception e) {
519 <            fail("unexpected exception");
519 >            unexpectedException();
520          }
521          Thread t = new Thread(new Runnable() {
522                  public void run() {
523                      try {
524                          lock.readLock().lockInterruptibly();
525 <                        fail("should throw");
525 >                        threadShouldThrow();
526                      }
527                      catch(InterruptedException success) {
528                      }
# Line 373 | Line 534 | public class ReentrantReadWriteLockTest
534              t.join();
535              lock.writeLock().unlock();
536          } catch(Exception e){
537 <            fail("unexpected exception");
537 >            unexpectedException();
538          }
539      }
540  
541 +    /**
542 +     * Calling await without holding lock throws IllegalMonitorStateException
543 +     */
544      public void testAwait_IllegalMonitor() {
545          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
546          final Condition c = lock.writeLock().newCondition();
547          try {
548              c.await();
549 <            fail("should throw");
549 >            shouldThrow();
550          }
551          catch (IllegalMonitorStateException success) {
552          }
553          catch (Exception ex) {
554 <            fail("should throw IMSE");
554 >            shouldThrow();
555          }
556      }
557  
558 +    /**
559 +     * Calling signal without holding lock throws IllegalMonitorStateException
560 +     */
561      public void testSignal_IllegalMonitor() {
562          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
563          final Condition c = lock.writeLock().newCondition();
564          try {
565              c.signal();
566 <            fail("should throw");
566 >            shouldThrow();
567          }
568          catch (IllegalMonitorStateException success) {
569          }
570          catch (Exception ex) {
571 <            fail("should throw IMSE");
571 >            unexpectedException();
572          }
573      }
574  
575 +    /**
576 +     * awaitNanos without a signal times out
577 +     */
578      public void testAwaitNanos_Timeout() {
579          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
580          final Condition c = lock.writeLock().newCondition();
# Line 415 | Line 585 | public class ReentrantReadWriteLockTest
585              lock.writeLock().unlock();
586          }
587          catch (Exception ex) {
588 <            fail("unexpected exception");
588 >            unexpectedException();
589          }
590      }
591  
592 +
593 +    /**
594 +     *  timed await without a signal times out
595 +     */
596      public void testAwait_Timeout() {
597          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
598          final Condition c = lock.writeLock().newCondition();
# Line 428 | Line 602 | public class ReentrantReadWriteLockTest
602              lock.writeLock().unlock();
603          }
604          catch (Exception ex) {
605 <            fail("unexpected exception");
605 >            unexpectedException();
606          }
607      }
608  
609 +    /**
610 +     * awaitUntil without a signal times out
611 +     */
612      public void testAwaitUntil_Timeout() {
613          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
614          final Condition c = lock.writeLock().newCondition();
# Line 442 | Line 619 | public class ReentrantReadWriteLockTest
619              lock.writeLock().unlock();
620          }
621          catch (Exception ex) {
622 <            fail("unexpected exception");
622 >            unexpectedException();
623          }
624      }
625  
626 +    /**
627 +     * await returns when signalled
628 +     */
629      public void testAwait() {
630          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
631          final Condition c = lock.writeLock().newCondition();
# Line 457 | Line 637 | public class ReentrantReadWriteLockTest
637                          lock.writeLock().unlock();
638                      }
639                      catch(InterruptedException e) {
640 <                        fail("unexpected exception");
640 >                        threadUnexpectedException();
641                      }
642                  }
643              });
# Line 472 | Line 652 | public class ReentrantReadWriteLockTest
652              assertFalse(t.isAlive());
653          }
654          catch (Exception ex) {
655 <            fail("unexpected exception");
655 >            unexpectedException();
656          }
657      }
658  
659 +    /**
660 +     * awaitUninterruptibly doesn't abort on interrupt
661 +     */
662      public void testAwaitUninterruptibly() {
663          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
664          final Condition c = lock.writeLock().newCondition();
# Line 494 | Line 677 | public class ReentrantReadWriteLockTest
677              lock.writeLock().lock();
678              c.signal();
679              lock.writeLock().unlock();
680 +            assert(t.isInterrupted());
681              t.join(SHORT_DELAY_MS);
682              assertFalse(t.isAlive());
683          }
684          catch (Exception ex) {
685 <            fail("unexpected exception");
685 >            unexpectedException();
686          }
687      }
688  
689 +    /**
690 +     * await is interruptible
691 +     */
692      public void testAwait_Interrupt() {
693          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
694          final Condition c = lock.writeLock().newCondition();
# Line 511 | Line 698 | public class ReentrantReadWriteLockTest
698                          lock.writeLock().lock();
699                          c.await();
700                          lock.writeLock().unlock();
701 <                        fail("should throw");
701 >                        threadShouldThrow();
702                      }
703                      catch(InterruptedException success) {
704                      }
# Line 526 | Line 713 | public class ReentrantReadWriteLockTest
713              assertFalse(t.isAlive());
714          }
715          catch (Exception ex) {
716 <            fail("unexpected exception");
716 >            unexpectedException();
717          }
718      }
719  
720 +    /**
721 +     * awaitNanos is interruptible
722 +     */
723      public void testAwaitNanos_Interrupt() {
724          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
725          final Condition c = lock.writeLock().newCondition();
# Line 539 | Line 729 | public class ReentrantReadWriteLockTest
729                          lock.writeLock().lock();
730                          c.awaitNanos(SHORT_DELAY_MS * 2 * 1000000);
731                          lock.writeLock().unlock();
732 <                        fail("should throw");
732 >                        threadShouldThrow();
733                      }
734                      catch(InterruptedException success) {
735                      }
# Line 554 | Line 744 | public class ReentrantReadWriteLockTest
744              assertFalse(t.isAlive());
745          }
746          catch (Exception ex) {
747 <            fail("unexpected exception");
747 >            unexpectedException();
748          }
749      }
750  
751 +    /**
752 +     * awaitUntil is interruptible
753 +     */
754      public void testAwaitUntil_Interrupt() {
755          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
756          final Condition c = lock.writeLock().newCondition();
# Line 568 | Line 761 | public class ReentrantReadWriteLockTest
761                          java.util.Date d = new java.util.Date();
762                          c.awaitUntil(new java.util.Date(d.getTime() + 10000));
763                          lock.writeLock().unlock();
764 <                        fail("should throw");
764 >                        threadShouldThrow();
765                      }
766                      catch(InterruptedException success) {
767                      }
# Line 583 | Line 776 | public class ReentrantReadWriteLockTest
776              assertFalse(t.isAlive());
777          }
778          catch (Exception ex) {
779 <            fail("unexpected exception");
779 >            unexpectedException();
780          }
781      }
782  
783 +    /**
784 +     * signalAll wakes up all threads
785 +     */
786      public void testSignalAll() {
787          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
788          final Condition c = lock.writeLock().newCondition();
# Line 598 | Line 794 | public class ReentrantReadWriteLockTest
794                          lock.writeLock().unlock();
795                      }
796                      catch(InterruptedException e) {
797 <                        fail("unexpected exception");
797 >                        threadUnexpectedException();
798                      }
799                  }
800              });
# Line 611 | Line 807 | public class ReentrantReadWriteLockTest
807                          lock.writeLock().unlock();
808                      }
809                      catch(InterruptedException e) {
810 <                        fail("unexpected exception");
810 >                        threadUnexpectedException();
811                      }
812                  }
813              });
# Line 629 | Line 825 | public class ReentrantReadWriteLockTest
825              assertFalse(t2.isAlive());
826          }
827          catch (Exception ex) {
828 <            fail("unexpected exception");
828 >            unexpectedException();
829          }
830      }
831  
832 +    /**
833 +     * A serialized lock deserializes as unlocked
834 +     */
835      public void testSerialization() {
836          ReentrantReadWriteLock l = new ReentrantReadWriteLock();
837          l.readLock().lock();
# Line 651 | Line 850 | public class ReentrantReadWriteLockTest
850              r.readLock().unlock();
851          } catch(Exception e){
852              e.printStackTrace();
853 <            fail("unexpected exception");
853 >            unexpectedException();
854 >        }
855 >    }
856 >
857 >    /**
858 >     * getQueueLength reports number of waiting threads
859 >     */
860 >    public void testGetQueueLength() {
861 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
862 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
863 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
864 >        try {
865 >            assertEquals(0, lock.getQueueLength());
866 >            lock.writeLock().lock();
867 >            t1.start();
868 >            Thread.sleep(SHORT_DELAY_MS);
869 >            assertEquals(1, lock.getQueueLength());
870 >            t2.start();
871 >            Thread.sleep(SHORT_DELAY_MS);
872 >            assertEquals(2, lock.getQueueLength());
873 >            t1.interrupt();
874 >            Thread.sleep(SHORT_DELAY_MS);
875 >            assertEquals(1, lock.getQueueLength());
876 >            lock.writeLock().unlock();
877 >            Thread.sleep(SHORT_DELAY_MS);
878 >            assertEquals(0, lock.getQueueLength());
879 >            t1.join();
880 >            t2.join();
881 >        } catch(Exception e){
882 >            unexpectedException();
883 >        }
884 >    }
885 >
886 >    /**
887 >     * getQueuedThreads includes waiting threads
888 >     */
889 >    public void testGetQueuedThreads() {
890 >        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
891 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
892 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
893 >        try {
894 >            assertTrue(lock.getQueuedThreads().isEmpty());
895 >            lock.writeLock().lock();
896 >            assertTrue(lock.getQueuedThreads().isEmpty());
897 >            t1.start();
898 >            Thread.sleep(SHORT_DELAY_MS);
899 >            assertTrue(lock.getQueuedThreads().contains(t1));
900 >            t2.start();
901 >            Thread.sleep(SHORT_DELAY_MS);
902 >            assertTrue(lock.getQueuedThreads().contains(t1));
903 >            assertTrue(lock.getQueuedThreads().contains(t2));
904 >            t1.interrupt();
905 >            Thread.sleep(SHORT_DELAY_MS);
906 >            assertFalse(lock.getQueuedThreads().contains(t1));
907 >            assertTrue(lock.getQueuedThreads().contains(t2));
908 >            lock.writeLock().unlock();
909 >            Thread.sleep(SHORT_DELAY_MS);
910 >            assertTrue(lock.getQueuedThreads().isEmpty());
911 >            t1.join();
912 >            t2.join();
913 >        } catch(Exception e){
914 >            unexpectedException();
915 >        }
916 >    }
917 >
918 >    /**
919 >     * hasWaiters returns true when a thread is waiting, else false
920 >     */
921 >    public void testHasWaiters() {
922 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
923 >        final ReentrantReadWriteLock.WriterConditionObject c = (ReentrantReadWriteLock.WriterConditionObject)(lock.writeLock().newCondition());
924 >        Thread t = new Thread(new Runnable() {
925 >                public void run() {
926 >                    try {
927 >                        lock.writeLock().lock();
928 >                        threadAssertFalse(c.hasWaiters());
929 >                        threadAssertEquals(0, c.getWaitQueueLength());
930 >                        c.await();
931 >                        lock.writeLock().unlock();
932 >                    }
933 >                    catch(InterruptedException e) {
934 >                        threadUnexpectedException();
935 >                    }
936 >                }
937 >            });
938 >
939 >        try {
940 >            t.start();
941 >            Thread.sleep(SHORT_DELAY_MS);
942 >            lock.writeLock().lock();
943 >            assertTrue(c.hasWaiters());
944 >            assertEquals(1, c.getWaitQueueLength());
945 >            c.signal();
946 >            lock.writeLock().unlock();
947 >            Thread.sleep(SHORT_DELAY_MS);
948 >            lock.writeLock().lock();
949 >            assertFalse(c.hasWaiters());
950 >            assertEquals(0, c.getWaitQueueLength());
951 >            lock.writeLock().unlock();
952 >            t.join(SHORT_DELAY_MS);
953 >            assertFalse(t.isAlive());
954 >        }
955 >        catch (Exception ex) {
956 >            unexpectedException();
957          }
958      }
959  
960 +    /**
961 +     * getWaitQueueLength returns number of waiting threads
962 +     */
963 +    public void testGetWaitQueueLength() {
964 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
965 +        final ReentrantReadWriteLock.WriterConditionObject c = (ReentrantReadWriteLock.WriterConditionObject)(lock.writeLock().newCondition());
966 +        Thread t1 = new Thread(new Runnable() {
967 +                public void run() {
968 +                    try {
969 +                        lock.writeLock().lock();
970 +                        threadAssertFalse(c.hasWaiters());
971 +                        threadAssertEquals(0, c.getWaitQueueLength());
972 +                        c.await();
973 +                        lock.writeLock().unlock();
974 +                    }
975 +                    catch(InterruptedException e) {
976 +                        threadUnexpectedException();
977 +                    }
978 +                }
979 +            });
980 +
981 +        Thread t2 = new Thread(new Runnable() {
982 +                public void run() {
983 +                    try {
984 +                        lock.writeLock().lock();
985 +                        threadAssertTrue(c.hasWaiters());
986 +                        threadAssertEquals(1, c.getWaitQueueLength());
987 +                        c.await();
988 +                        lock.writeLock().unlock();
989 +                    }
990 +                    catch(InterruptedException e) {
991 +                        threadUnexpectedException();
992 +                    }
993 +                }
994 +            });
995 +
996 +        try {
997 +            t1.start();
998 +            Thread.sleep(SHORT_DELAY_MS);
999 +            t2.start();
1000 +            Thread.sleep(SHORT_DELAY_MS);
1001 +            lock.writeLock().lock();
1002 +            assertTrue(c.hasWaiters());
1003 +            assertEquals(2, c.getWaitQueueLength());
1004 +            c.signalAll();
1005 +            lock.writeLock().unlock();
1006 +            Thread.sleep(SHORT_DELAY_MS);
1007 +            lock.writeLock().lock();
1008 +            assertFalse(c.hasWaiters());
1009 +            assertEquals(0, c.getWaitQueueLength());
1010 +            lock.writeLock().unlock();
1011 +            t1.join(SHORT_DELAY_MS);
1012 +            t2.join(SHORT_DELAY_MS);
1013 +            assertFalse(t1.isAlive());
1014 +            assertFalse(t2.isAlive());
1015 +        }
1016 +        catch (Exception ex) {
1017 +            unexpectedException();
1018 +        }
1019 +    }
1020 +
1021 +    /**
1022 +     * getWaitingThreads returns only and all waiting threads
1023 +     */
1024 +    public void testGetWaitingThreads() {
1025 +        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();  
1026 +        final PublicReentrantReadWriteLock.PublicCondition c = (PublicReentrantReadWriteLock.PublicCondition)lock.newCondition();
1027 +        Thread t1 = new Thread(new Runnable() {
1028 +                public void run() {
1029 +                    try {
1030 +                        lock.writeLock().lock();
1031 +                        threadAssertTrue(c.getWaitingThreads().isEmpty());
1032 +                        c.await();
1033 +                        lock.writeLock().unlock();
1034 +                    }
1035 +                    catch(InterruptedException e) {
1036 +                        threadUnexpectedException();
1037 +                    }
1038 +                }
1039 +            });
1040 +
1041 +        Thread t2 = new Thread(new Runnable() {
1042 +                public void run() {
1043 +                    try {
1044 +                        lock.writeLock().lock();
1045 +                        threadAssertFalse(c.getWaitingThreads().isEmpty());
1046 +                        c.await();
1047 +                        lock.writeLock().unlock();
1048 +                    }
1049 +                    catch(InterruptedException e) {
1050 +                        threadUnexpectedException();
1051 +                    }
1052 +                }
1053 +            });
1054 +
1055 +        try {
1056 +            lock.writeLock().lock();
1057 +            assertTrue(c.getWaitingThreads().isEmpty());
1058 +            lock.writeLock().unlock();
1059 +            t1.start();
1060 +            Thread.sleep(SHORT_DELAY_MS);
1061 +            t2.start();
1062 +            Thread.sleep(SHORT_DELAY_MS);
1063 +            lock.writeLock().lock();
1064 +            assertTrue(c.hasWaiters());
1065 +            assertTrue(c.getWaitingThreads().contains(t1));
1066 +            assertTrue(c.getWaitingThreads().contains(t2));
1067 +            c.signalAll();
1068 +            lock.writeLock().unlock();
1069 +            Thread.sleep(SHORT_DELAY_MS);
1070 +            lock.writeLock().lock();
1071 +            assertFalse(c.hasWaiters());
1072 +            assertTrue(c.getWaitingThreads().isEmpty());
1073 +            lock.writeLock().unlock();
1074 +            t1.join(SHORT_DELAY_MS);
1075 +            t2.join(SHORT_DELAY_MS);
1076 +            assertFalse(t1.isAlive());
1077 +            assertFalse(t2.isAlive());
1078 +        }
1079 +        catch (Exception ex) {
1080 +            unexpectedException();
1081 +        }
1082 +    }
1083  
1084   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines