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.3 by dl, Sun Sep 14 20:42:40 2003 UTC vs.
Revision 1.11 by dl, Sat Dec 27 18:27:02 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 JSR166TestCase {
15      public static void main(String[] args) {
# Line 18 | Line 19 | public class ReentrantReadWriteLockTest
19          return new TestSuite(ReentrantReadWriteLockTest.class);
20      }
21  
22 <    static int HOLD_COUNT_TEST_LIMIT = 20;
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 >    /**
37 >     * A runnable calling lockInterruptibly that expects to be
38 >     * interrupted
39 >     */
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 >    }
60  
61 <    /*
62 <     * Unlocks an unlocked lock, throws Illegal Monitor State
25 <     *
61 >    /**
62 >     * Constructor sets given fairness, and is in unlocked state
63       */
64 <    public void testIllegalMonitorStateException(){
64 >    public void testConstructor() {
65          ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
66 <        try{
67 <            rl.writeLock().unlock();
68 <            fail("Should of thown Illegal Monitor State Exception");
66 >        assertFalse(rl.isFair());
67 >        assertFalse(rl.isWriteLocked());
68 >        assertEquals(0, rl.getReadLockCount());
69 >        ReentrantReadWriteLock r2 = new ReentrantReadWriteLock(true);
70 >        assertTrue(r2.isFair());
71 >        assertFalse(r2.isWriteLocked());
72 >        assertEquals(0, r2.getReadLockCount());
73 >    }
74 >
75 >    /**
76 >     * write-locking and read-locking an unlocked lock succeed
77 >     */
78 >    public void testLock() {
79 >        ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
80 >        rl.writeLock().lock();
81 >        assertTrue(rl.isWriteLocked());
82 >        assertTrue(rl.isWriteLockedByCurrentThread());
83 >        assertEquals(0, rl.getReadLockCount());
84 >        rl.writeLock().unlock();
85 >        assertFalse(rl.isWriteLocked());
86 >        assertFalse(rl.isWriteLockedByCurrentThread());
87 >        assertEquals(0, rl.getReadLockCount());
88 >        rl.readLock().lock();
89 >        assertFalse(rl.isWriteLocked());
90 >        assertFalse(rl.isWriteLockedByCurrentThread());
91 >        assertEquals(1, rl.getReadLockCount());
92 >        rl.readLock().unlock();
93 >        assertFalse(rl.isWriteLocked());
94 >        assertFalse(rl.isWriteLockedByCurrentThread());
95 >        assertEquals(0, rl.getReadLockCount());
96 >    }
97 >
98 >
99 >    /**
100 >     * locking an unlocked fair lock succeeds
101 >     */
102 >    public void testFairLock() {
103 >        ReentrantReadWriteLock rl = new ReentrantReadWriteLock(true);
104 >        rl.writeLock().lock();
105 >        assertTrue(rl.isWriteLocked());
106 >        assertTrue(rl.isWriteLockedByCurrentThread());
107 >        assertEquals(0, rl.getReadLockCount());
108 >        rl.writeLock().unlock();
109 >        assertFalse(rl.isWriteLocked());
110 >        assertFalse(rl.isWriteLockedByCurrentThread());
111 >        assertEquals(0, rl.getReadLockCount());
112 >        rl.readLock().lock();
113 >        assertFalse(rl.isWriteLocked());
114 >        assertFalse(rl.isWriteLockedByCurrentThread());
115 >        assertEquals(1, rl.getReadLockCount());
116 >        rl.readLock().unlock();
117 >        assertFalse(rl.isWriteLocked());
118 >        assertFalse(rl.isWriteLockedByCurrentThread());
119 >        assertEquals(0, rl.getReadLockCount());
120 >    }
121  
122 <        }catch(IllegalMonitorStateException success){}
122 >    /**
123 >     * getWriteHoldCount returns number of recursive holds
124 >     */
125 >    public void testGetHoldCount() {
126 >        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
127 >        for(int i = 1; i <= SIZE; i++) {
128 >            lock.writeLock().lock();
129 >            assertEquals(i,lock.getWriteHoldCount());
130 >        }
131 >        for(int i = SIZE; i > 0; i--) {
132 >            lock.writeLock().unlock();
133 >            assertEquals(i-1,lock.getWriteHoldCount());
134 >        }
135      }
136 +    
137  
138 +    /**
139 +     * write-unlocking an unlocked lock throws IllegalMonitorStateException
140 +     */
141 +    public void testUnlock_IllegalMonitorStateException() {
142 +        ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
143 +        try {
144 +            rl.writeLock().unlock();
145 +            shouldThrow();
146 +        } catch(IllegalMonitorStateException success){}
147 +    }
148  
149  
150 <    public void testInterruptedException(){
150 >    /**
151 >     * write-lockInterruptibly is interruptible
152 >     */
153 >    public void testWriteLockInterruptibly_Interrupted() {
154          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
155          lock.writeLock().lock();
156          Thread t = new Thread(new Runnable() {
157 <                public void run(){
158 <                    try{
157 >                public void run() {
158 >                    try {
159                          lock.writeLock().lockInterruptibly();
160 <                        threadFail("should throw");
161 <                    }catch(InterruptedException success){}
160 >                        threadShouldThrow();
161 >                    } catch(InterruptedException success){}
162                  }
163              });
164          try {
# Line 52 | Line 167 | public class ReentrantReadWriteLockTest
167              lock.writeLock().unlock();
168              t.join();
169          } catch(Exception e){
170 <            fail("unexpected exception");
170 >            unexpectedException();
171          }
172      }
173  
174 <    public void testInterruptedException2(){
174 >    /**
175 >     * timed write-trylock is interruptible
176 >     */
177 >    public void testWriteTryLock_Interrupted() {
178          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
179          lock.writeLock().lock();
180          Thread t = new Thread(new Runnable() {
181 <                public void run(){
182 <                    try{
181 >                public void run() {
182 >                    try {
183                          lock.writeLock().tryLock(1000,TimeUnit.MILLISECONDS);
184 <                        threadFail("should throw");
185 <                    }catch(InterruptedException success){}
184 >                        threadShouldThrow();
185 >                    } catch(InterruptedException success){}
186                  }
187              });
188          try {
# Line 73 | Line 191 | public class ReentrantReadWriteLockTest
191              lock.writeLock().unlock();
192              t.join();
193          } catch(Exception e){
194 <            fail("unexpected exception");
194 >            unexpectedException();
195          }
196      }
197  
198 <    public void testInterruptedException3(){
198 >    /**
199 >     * read-lockInterruptibly is interruptible
200 >     */
201 >    public void testReadLockInterruptibly_Interrupted() {
202          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
203          lock.writeLock().lock();
204          Thread t = new Thread(new Runnable() {
205 <                public void run(){
206 <                    try{
205 >                public void run() {
206 >                    try {
207                          lock.readLock().lockInterruptibly();
208 <                        threadFail("should throw");
209 <                    }catch(InterruptedException success){}
208 >                        threadShouldThrow();
209 >                    } catch(InterruptedException success){}
210                  }
211              });
212          try {
# Line 94 | Line 215 | public class ReentrantReadWriteLockTest
215              lock.writeLock().unlock();
216              t.join();
217          } catch(Exception e){
218 <            fail("unexpected exception");
218 >            unexpectedException();
219          }
220      }
221  
222 <    public void testInterruptedException4(){
222 >    /**
223 >     * timed read-trylock is interruptible
224 >     */
225 >    public void testReadTryLock_Interrupted() {
226          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
227          lock.writeLock().lock();
228          Thread t = new Thread(new Runnable() {
229 <                public void run(){
230 <                    try{
229 >                public void run() {
230 >                    try {
231                          lock.readLock().tryLock(1000,TimeUnit.MILLISECONDS);
232 <                        threadFail("should throw");
233 <                    }catch(InterruptedException success){}
232 >                        threadShouldThrow();
233 >                    } catch(InterruptedException success){}
234                  }
235              });
236          try {
# Line 114 | Line 238 | public class ReentrantReadWriteLockTest
238              t.interrupt();
239              t.join();
240          } catch(Exception e){
241 <            fail("unexpected exception");
241 >            unexpectedException();
242          }
243      }
244  
245      
246 <    public void testTryLockWhenLocked() {
246 >    /**
247 >     * write-trylock fails if locked
248 >     */
249 >    public void testWriteTryLockWhenLocked() {
250          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
251          lock.writeLock().lock();
252          Thread t = new Thread(new Runnable() {
253 <                public void run(){
253 >                public void run() {
254                      threadAssertFalse(lock.writeLock().tryLock());
255                  }
256              });
# Line 132 | Line 259 | public class ReentrantReadWriteLockTest
259              t.join();
260              lock.writeLock().unlock();
261          } catch(Exception e){
262 <            fail("unexpected exception");
262 >            unexpectedException();
263          }
264      }
265  
266 <    public void testTryLockWhenLocked2() {
266 >    /**
267 >     * read-trylock fails if locked
268 >     */
269 >    public void testReadTryLockWhenLocked() {
270          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
271          lock.writeLock().lock();
272          Thread t = new Thread(new Runnable() {
273 <                public void run(){
273 >                public void run() {
274                      threadAssertFalse(lock.readLock().tryLock());
275                  }
276              });
# Line 149 | Line 279 | public class ReentrantReadWriteLockTest
279              t.join();
280              lock.writeLock().unlock();
281          } catch(Exception e){
282 <            fail("unexpected exception");
282 >            unexpectedException();
283          }
284      }
285  
286 +    /**
287 +     * Multiple threads can hold a read lock when not write-locked
288 +     */
289      public void testMultipleReadLocks() {
290          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
291          lock.readLock().lock();
292          Thread t = new Thread(new Runnable() {
293 <                public void run(){
293 >                public void run() {
294                      threadAssertTrue(lock.readLock().tryLock());
295                      lock.readLock().unlock();
296                  }
# Line 167 | Line 300 | public class ReentrantReadWriteLockTest
300              t.join();
301              lock.readLock().unlock();
302          } catch(Exception e){
303 <            fail("unexpected exception");
303 >            unexpectedException();
304          }
305      }
306  
307 +    /**
308 +     * A writelock succeeds after reading threads unlock
309 +     */
310      public void testWriteAfterMultipleReadLocks() {
311          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
312          lock.readLock().lock();
313          Thread t1 = new Thread(new Runnable() {
314 <                public void run(){
314 >                public void run() {
315                      lock.readLock().lock();
316                      lock.readLock().unlock();
317                  }
318              });
319          Thread t2 = new Thread(new Runnable() {
320 <                public void run(){
320 >                public void run() {
321                      lock.writeLock().lock();
322                      lock.writeLock().unlock();
323                  }
# Line 198 | Line 334 | public class ReentrantReadWriteLockTest
334              assertTrue(!t2.isAlive());
335            
336          } catch(Exception e){
337 <            fail("unexpected exception");
337 >            unexpectedException();
338          }
339      }
340  
341 +    /**
342 +     * Readlocks succeed after a writing thread unlocks
343 +     */
344      public void testReadAfterWriteLock() {
345          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
346          lock.writeLock().lock();
347          Thread t1 = new Thread(new Runnable() {
348 <                public void run(){
348 >                public void run() {
349                      lock.readLock().lock();
350                      lock.readLock().unlock();
351                  }
352              });
353          Thread t2 = new Thread(new Runnable() {
354 <                public void run(){
354 >                public void run() {
355                      lock.readLock().lock();
356                      lock.readLock().unlock();
357                  }
# Line 229 | Line 368 | public class ReentrantReadWriteLockTest
368              assertTrue(!t2.isAlive());
369            
370          } catch(Exception e){
371 <            fail("unexpected exception");
371 >            unexpectedException();
372          }
373      }
374  
375  
376 +    /**
377 +     * Read trylock succeeds if readlocked but not writelocked
378 +     */
379      public void testTryLockWhenReadLocked() {
380          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
381          lock.readLock().lock();
382          Thread t = new Thread(new Runnable() {
383 <                public void run(){
383 >                public void run() {
384                      threadAssertTrue(lock.readLock().tryLock());
385                      lock.readLock().unlock();
386                  }
# Line 248 | Line 390 | public class ReentrantReadWriteLockTest
390              t.join();
391              lock.readLock().unlock();
392          } catch(Exception e){
393 <            fail("unexpected exception");
393 >            unexpectedException();
394          }
395      }
396  
397      
398  
399 +    /**
400 +     * write trylock fails when readlocked
401 +     */
402      public void testWriteTryLockWhenReadLocked() {
403          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
404          lock.readLock().lock();
405          Thread t = new Thread(new Runnable() {
406 <                public void run(){
406 >                public void run() {
407                      threadAssertFalse(lock.writeLock().tryLock());
408                  }
409              });
# Line 267 | Line 412 | public class ReentrantReadWriteLockTest
412              t.join();
413              lock.readLock().unlock();
414          } catch(Exception e){
415 <            fail("unexpected exception");
415 >            unexpectedException();
416          }
417      }
418  
419      
420  
421 <    public void testTryLock_Timeout(){
421 >    /**
422 >     * write timed trylock times out if locked
423 >     */
424 >    public void testWriteTryLock_Timeout() {
425          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
426          lock.writeLock().lock();
427          Thread t = new Thread(new Runnable() {
428 <                public void run(){
428 >                public void run() {
429                      try {
430                          threadAssertFalse(lock.writeLock().tryLock(1, TimeUnit.MILLISECONDS));
431                      } catch (Exception ex) {
432 <                        threadFail("unexpected exception");
432 >                        threadUnexpectedException();
433                      }
434                  }
435              });
# Line 290 | Line 438 | public class ReentrantReadWriteLockTest
438              t.join();
439              lock.writeLock().unlock();
440          } catch(Exception e){
441 <            fail("unexpected exception");
441 >            unexpectedException();
442          }
443      }
444  
445 <    public void testTryLock_Timeout2(){
445 >    /**
446 >     * read timed trylock times out if write-locked
447 >     */
448 >    public void testReadTryLock_Timeout() {
449          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
450          lock.writeLock().lock();
451          Thread t = new Thread(new Runnable() {
452 <                public void run(){
452 >                public void run() {
453                      try {
454                          threadAssertFalse(lock.readLock().tryLock(1, TimeUnit.MILLISECONDS));
455                      } catch (Exception ex) {
456 <                        threadFail("unexpected exception");
456 >                        threadUnexpectedException();
457                      }
458                  }
459              });
# Line 311 | Line 462 | public class ReentrantReadWriteLockTest
462              t.join();
463              lock.writeLock().unlock();
464          } catch(Exception e){
465 <            fail("unexpected exception");
465 >            unexpectedException();
466          }
467      }
468  
469  
470 <    public void testLockInterruptibly() {
470 >    /**
471 >     * write lockInterruptibly succeeds if lock free else is interruptible
472 >     */
473 >    public void testWriteLockInterruptibly() {
474          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
475          try {
476              lock.writeLock().lockInterruptibly();
477          } catch(Exception e) {
478 <            fail("unexpected exception");
478 >            unexpectedException();
479          }
480          Thread t = new Thread(new Runnable() {
481                  public void run() {
482                      try {
483                          lock.writeLock().lockInterruptibly();
484 <                        threadFail("should throw");
484 >                        threadShouldThrow();
485                      }
486                      catch(InterruptedException success) {
487                      }
# Line 339 | Line 493 | public class ReentrantReadWriteLockTest
493              t.join();
494              lock.writeLock().unlock();
495          } catch(Exception e){
496 <            fail("unexpected exception");
496 >            unexpectedException();
497          }
498      }
499  
500 <    public void testLockInterruptibly2() {
500 >    /**
501 >     *  read lockInterruptibly succeeds if lock free else is interruptible
502 >     */
503 >    public void testReadLockInterruptibly() {
504          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
505          try {
506              lock.writeLock().lockInterruptibly();
507          } catch(Exception e) {
508 <            fail("unexpected exception");
508 >            unexpectedException();
509          }
510          Thread t = new Thread(new Runnable() {
511                  public void run() {
512                      try {
513                          lock.readLock().lockInterruptibly();
514 <                        threadFail("should throw");
514 >                        threadShouldThrow();
515                      }
516                      catch(InterruptedException success) {
517                      }
# Line 366 | Line 523 | public class ReentrantReadWriteLockTest
523              t.join();
524              lock.writeLock().unlock();
525          } catch(Exception e){
526 <            fail("unexpected exception");
526 >            unexpectedException();
527          }
528      }
529  
530 +    /**
531 +     * Calling await without holding lock throws IllegalMonitorStateException
532 +     */
533      public void testAwait_IllegalMonitor() {
534          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
535          final Condition c = lock.writeLock().newCondition();
536          try {
537              c.await();
538 <            fail("should throw");
538 >            shouldThrow();
539          }
540          catch (IllegalMonitorStateException success) {
541          }
542          catch (Exception ex) {
543 <            fail("should throw IMSE");
543 >            shouldThrow();
544          }
545      }
546  
547 +    /**
548 +     * Calling signal without holding lock throws IllegalMonitorStateException
549 +     */
550      public void testSignal_IllegalMonitor() {
551          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
552          final Condition c = lock.writeLock().newCondition();
553          try {
554              c.signal();
555 <            fail("should throw");
555 >            shouldThrow();
556          }
557          catch (IllegalMonitorStateException success) {
558          }
559          catch (Exception ex) {
560 <            fail("should throw IMSE");
560 >            unexpectedException();
561          }
562      }
563  
564 +    /**
565 +     * awaitNanos without a signal times out
566 +     */
567      public void testAwaitNanos_Timeout() {
568          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
569          final Condition c = lock.writeLock().newCondition();
# Line 408 | Line 574 | public class ReentrantReadWriteLockTest
574              lock.writeLock().unlock();
575          }
576          catch (Exception ex) {
577 <            fail("unexpected exception");
577 >            unexpectedException();
578          }
579      }
580  
581 +
582 +    /**
583 +     *  timed await without a signal times out
584 +     */
585      public void testAwait_Timeout() {
586          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
587          final Condition c = lock.writeLock().newCondition();
# Line 421 | Line 591 | public class ReentrantReadWriteLockTest
591              lock.writeLock().unlock();
592          }
593          catch (Exception ex) {
594 <            fail("unexpected exception");
594 >            unexpectedException();
595          }
596      }
597  
598 +    /**
599 +     * awaitUntil without a signal times out
600 +     */
601      public void testAwaitUntil_Timeout() {
602          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
603          final Condition c = lock.writeLock().newCondition();
# Line 435 | Line 608 | public class ReentrantReadWriteLockTest
608              lock.writeLock().unlock();
609          }
610          catch (Exception ex) {
611 <            fail("unexpected exception");
611 >            unexpectedException();
612          }
613      }
614  
615 +    /**
616 +     * await returns when signalled
617 +     */
618      public void testAwait() {
619          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
620          final Condition c = lock.writeLock().newCondition();
# Line 450 | Line 626 | public class ReentrantReadWriteLockTest
626                          lock.writeLock().unlock();
627                      }
628                      catch(InterruptedException e) {
629 <                        threadFail("unexpected exception");
629 >                        threadUnexpectedException();
630                      }
631                  }
632              });
# Line 465 | Line 641 | public class ReentrantReadWriteLockTest
641              assertFalse(t.isAlive());
642          }
643          catch (Exception ex) {
644 <            fail("unexpected exception");
644 >            unexpectedException();
645          }
646      }
647  
648 +    /**
649 +     * awaitUninterruptibly doesn't abort on interrupt
650 +     */
651      public void testAwaitUninterruptibly() {
652          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
653          final Condition c = lock.writeLock().newCondition();
# Line 487 | Line 666 | public class ReentrantReadWriteLockTest
666              lock.writeLock().lock();
667              c.signal();
668              lock.writeLock().unlock();
669 +            assert(t.isInterrupted());
670              t.join(SHORT_DELAY_MS);
671              assertFalse(t.isAlive());
672          }
673          catch (Exception ex) {
674 <            fail("unexpected exception");
674 >            unexpectedException();
675          }
676      }
677  
678 +    /**
679 +     * await is interruptible
680 +     */
681      public void testAwait_Interrupt() {
682          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
683          final Condition c = lock.writeLock().newCondition();
# Line 504 | Line 687 | public class ReentrantReadWriteLockTest
687                          lock.writeLock().lock();
688                          c.await();
689                          lock.writeLock().unlock();
690 <                        threadFail("should throw");
690 >                        threadShouldThrow();
691                      }
692                      catch(InterruptedException success) {
693                      }
# Line 519 | Line 702 | public class ReentrantReadWriteLockTest
702              assertFalse(t.isAlive());
703          }
704          catch (Exception ex) {
705 <            fail("unexpected exception");
705 >            unexpectedException();
706          }
707      }
708  
709 +    /**
710 +     * awaitNanos is interruptible
711 +     */
712      public void testAwaitNanos_Interrupt() {
713          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
714          final Condition c = lock.writeLock().newCondition();
# Line 532 | Line 718 | public class ReentrantReadWriteLockTest
718                          lock.writeLock().lock();
719                          c.awaitNanos(SHORT_DELAY_MS * 2 * 1000000);
720                          lock.writeLock().unlock();
721 <                        threadFail("should throw");
721 >                        threadShouldThrow();
722                      }
723                      catch(InterruptedException success) {
724                      }
# Line 547 | Line 733 | public class ReentrantReadWriteLockTest
733              assertFalse(t.isAlive());
734          }
735          catch (Exception ex) {
736 <            fail("unexpected exception");
736 >            unexpectedException();
737          }
738      }
739  
740 +    /**
741 +     * awaitUntil is interruptible
742 +     */
743      public void testAwaitUntil_Interrupt() {
744          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
745          final Condition c = lock.writeLock().newCondition();
# Line 561 | Line 750 | public class ReentrantReadWriteLockTest
750                          java.util.Date d = new java.util.Date();
751                          c.awaitUntil(new java.util.Date(d.getTime() + 10000));
752                          lock.writeLock().unlock();
753 <                        threadFail("should throw");
753 >                        threadShouldThrow();
754                      }
755                      catch(InterruptedException success) {
756                      }
# Line 576 | Line 765 | public class ReentrantReadWriteLockTest
765              assertFalse(t.isAlive());
766          }
767          catch (Exception ex) {
768 <            fail("unexpected exception");
768 >            unexpectedException();
769          }
770      }
771  
772 +    /**
773 +     * signalAll wakes up all threads
774 +     */
775      public void testSignalAll() {
776          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
777          final Condition c = lock.writeLock().newCondition();
# Line 591 | Line 783 | public class ReentrantReadWriteLockTest
783                          lock.writeLock().unlock();
784                      }
785                      catch(InterruptedException e) {
786 <                        threadFail("unexpected exception");
786 >                        threadUnexpectedException();
787                      }
788                  }
789              });
# Line 604 | Line 796 | public class ReentrantReadWriteLockTest
796                          lock.writeLock().unlock();
797                      }
798                      catch(InterruptedException e) {
799 <                        threadFail("unexpected exception");
799 >                        threadUnexpectedException();
800                      }
801                  }
802              });
# Line 622 | Line 814 | public class ReentrantReadWriteLockTest
814              assertFalse(t2.isAlive());
815          }
816          catch (Exception ex) {
817 <            fail("unexpected exception");
817 >            unexpectedException();
818          }
819      }
820  
821 +    /**
822 +     * A serialized lock deserializes as unlocked
823 +     */
824      public void testSerialization() {
825          ReentrantReadWriteLock l = new ReentrantReadWriteLock();
826          l.readLock().lock();
# Line 644 | Line 839 | public class ReentrantReadWriteLockTest
839              r.readLock().unlock();
840          } catch(Exception e){
841              e.printStackTrace();
842 <            fail("unexpected exception");
842 >            unexpectedException();
843 >        }
844 >    }
845 >
846 >    /**
847 >     * getQueueLength reports number of waiting threads
848 >     */
849 >    public void testGetQueueLength() {
850 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
851 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
852 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
853 >        try {
854 >            assertEquals(0, lock.getQueueLength());
855 >            lock.writeLock().lock();
856 >            t1.start();
857 >            Thread.sleep(SHORT_DELAY_MS);
858 >            assertEquals(1, lock.getQueueLength());
859 >            t2.start();
860 >            Thread.sleep(SHORT_DELAY_MS);
861 >            assertEquals(2, lock.getQueueLength());
862 >            t1.interrupt();
863 >            Thread.sleep(SHORT_DELAY_MS);
864 >            assertEquals(1, lock.getQueueLength());
865 >            lock.writeLock().unlock();
866 >            Thread.sleep(SHORT_DELAY_MS);
867 >            assertEquals(0, lock.getQueueLength());
868 >            t1.join();
869 >            t2.join();
870 >        } catch(Exception e){
871 >            unexpectedException();
872 >        }
873 >    }
874 >
875 >    /**
876 >     * getQueuedThreads includes waiting threads
877 >     */
878 >    public void testGetQueuedThreads() {
879 >        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
880 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
881 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
882 >        try {
883 >            assertTrue(lock.getQueuedThreads().isEmpty());
884 >            lock.writeLock().lock();
885 >            assertTrue(lock.getQueuedThreads().isEmpty());
886 >            t1.start();
887 >            Thread.sleep(SHORT_DELAY_MS);
888 >            assertTrue(lock.getQueuedThreads().contains(t1));
889 >            t2.start();
890 >            Thread.sleep(SHORT_DELAY_MS);
891 >            assertTrue(lock.getQueuedThreads().contains(t1));
892 >            assertTrue(lock.getQueuedThreads().contains(t2));
893 >            t1.interrupt();
894 >            Thread.sleep(SHORT_DELAY_MS);
895 >            assertFalse(lock.getQueuedThreads().contains(t1));
896 >            assertTrue(lock.getQueuedThreads().contains(t2));
897 >            lock.writeLock().unlock();
898 >            Thread.sleep(SHORT_DELAY_MS);
899 >            assertTrue(lock.getQueuedThreads().isEmpty());
900 >            t1.join();
901 >            t2.join();
902 >        } catch(Exception e){
903 >            unexpectedException();
904 >        }
905 >    }
906 >
907 >    /**
908 >     * hasWaiters returns true when a thread is waiting, else false
909 >     */
910 >    public void testHasWaiters() {
911 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
912 >        final AbstractQueuedSynchronizer.ConditionObject c = (lock.writeLock().newCondition());
913 >        Thread t = new Thread(new Runnable() {
914 >                public void run() {
915 >                    try {
916 >                        lock.writeLock().lock();
917 >                        threadAssertFalse(c.hasWaiters());
918 >                        threadAssertEquals(0, c.getWaitQueueLength());
919 >                        c.await();
920 >                        lock.writeLock().unlock();
921 >                    }
922 >                    catch(InterruptedException e) {
923 >                        threadUnexpectedException();
924 >                    }
925 >                }
926 >            });
927 >
928 >        try {
929 >            t.start();
930 >            Thread.sleep(SHORT_DELAY_MS);
931 >            lock.writeLock().lock();
932 >            assertTrue(c.hasWaiters());
933 >            assertEquals(1, c.getWaitQueueLength());
934 >            c.signal();
935 >            lock.writeLock().unlock();
936 >            Thread.sleep(SHORT_DELAY_MS);
937 >            lock.writeLock().lock();
938 >            assertFalse(c.hasWaiters());
939 >            assertEquals(0, c.getWaitQueueLength());
940 >            lock.writeLock().unlock();
941 >            t.join(SHORT_DELAY_MS);
942 >            assertFalse(t.isAlive());
943 >        }
944 >        catch (Exception ex) {
945 >            unexpectedException();
946          }
947      }
948  
949 +    /**
950 +     * getWaitQueueLength returns number of waiting threads
951 +     */
952 +    public void testGetWaitQueueLength() {
953 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
954 +        final AbstractQueuedSynchronizer.ConditionObject c = (lock.writeLock().newCondition());
955 +        Thread t1 = new Thread(new Runnable() {
956 +                public void run() {
957 +                    try {
958 +                        lock.writeLock().lock();
959 +                        threadAssertFalse(c.hasWaiters());
960 +                        threadAssertEquals(0, c.getWaitQueueLength());
961 +                        c.await();
962 +                        lock.writeLock().unlock();
963 +                    }
964 +                    catch(InterruptedException e) {
965 +                        threadUnexpectedException();
966 +                    }
967 +                }
968 +            });
969 +
970 +        Thread t2 = new Thread(new Runnable() {
971 +                public void run() {
972 +                    try {
973 +                        lock.writeLock().lock();
974 +                        threadAssertTrue(c.hasWaiters());
975 +                        threadAssertEquals(1, c.getWaitQueueLength());
976 +                        c.await();
977 +                        lock.writeLock().unlock();
978 +                    }
979 +                    catch(InterruptedException e) {
980 +                        threadUnexpectedException();
981 +                    }
982 +                }
983 +            });
984  
985 +        try {
986 +            t1.start();
987 +            Thread.sleep(SHORT_DELAY_MS);
988 +            t2.start();
989 +            Thread.sleep(SHORT_DELAY_MS);
990 +            lock.writeLock().lock();
991 +            assertTrue(c.hasWaiters());
992 +            assertEquals(2, c.getWaitQueueLength());
993 +            c.signalAll();
994 +            lock.writeLock().unlock();
995 +            Thread.sleep(SHORT_DELAY_MS);
996 +            lock.writeLock().lock();
997 +            assertFalse(c.hasWaiters());
998 +            assertEquals(0, c.getWaitQueueLength());
999 +            lock.writeLock().unlock();
1000 +            t1.join(SHORT_DELAY_MS);
1001 +            t2.join(SHORT_DELAY_MS);
1002 +            assertFalse(t1.isAlive());
1003 +            assertFalse(t2.isAlive());
1004 +        }
1005 +        catch (Exception ex) {
1006 +            unexpectedException();
1007 +        }
1008 +    }
1009   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines