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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines