ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ReentrantLockTest.java
(Generate patch)

Comparing jsr166/src/test/tck/ReentrantLockTest.java (file contents):
Revision 1.5 by dl, Sat Sep 20 00:31:57 2003 UTC vs.
Revision 1.25 by dl, Thu May 18 10:29:23 2006 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.*;
# Line 19 | Line 20 | public class ReentrantLockTest extends J
20          return new TestSuite(ReentrantLockTest.class);
21      }
22  
23 <    static int HOLD_COUNT_TEST_LIMIT = 20;
24 <
23 >    /**
24 >     * A runnable calling lockInterruptibly
25 >     */
26      class InterruptibleLockRunnable implements Runnable {
27          final ReentrantLock lock;
28          InterruptibleLockRunnable(ReentrantLock l) { lock = l; }
29 <        public void run(){
30 <            try{
29 >        public void run() {
30 >            try {
31                  lock.lockInterruptibly();
32              } catch(InterruptedException success){}
33          }
34      }
35  
36 <    // Same, except must interrupt
36 >
37 >    /**
38 >     * A runnable calling lockInterruptibly that expects to be
39 >     * interrupted
40 >     */
41      class InterruptedLockRunnable implements Runnable {
42          final ReentrantLock lock;
43          InterruptedLockRunnable(ReentrantLock l) { lock = l; }
44 <        public void run(){
45 <            try{
44 >        public void run() {
45 >            try {
46                  lock.lockInterruptibly();
47 <                threadFail("should throw");
47 >                threadShouldThrow();
48              } catch(InterruptedException success){}
49          }
50      }
51  
52      /**
53 <     * To expose protected methods
53 >     * Subclass to expose protected methods
54       */
55 <    static class MyReentrantLock extends ReentrantLock {
56 <        MyReentrantLock() { super(); }
55 >    static class PublicReentrantLock extends ReentrantLock {
56 >        PublicReentrantLock() { super(); }
57          public Collection<Thread> getQueuedThreads() {
58              return super.getQueuedThreads();
59          }
60 <        public ConditionObject newCondition() {
61 <            return new MyCondition(this);
60 >        public Collection<Thread> getWaitingThreads(Condition c) {
61 >            return super.getWaitingThreads(c);
62          }
63  
58        static class MyCondition extends ReentrantLock.ConditionObject {
59            MyCondition(MyReentrantLock l) { super(l); }
60            public Collection<Thread> getWaitingThreads() {
61                return super.getWaitingThreads();
62            }
63        }
64  
65      }
66  
67 <    /*
67 >    /**
68 >     * Constructor sets given fairness
69 >     */
70 >    public void testConstructor() {
71 >        ReentrantLock rl = new ReentrantLock();
72 >        assertFalse(rl.isFair());
73 >        ReentrantLock r2 = new ReentrantLock(true);
74 >        assertTrue(r2.isFair());
75 >    }
76 >
77 >    /**
78 >     * locking an unlocked lock succeeds
79 >     */
80 >    public void testLock() {
81 >        ReentrantLock rl = new ReentrantLock();
82 >        rl.lock();
83 >        assertTrue(rl.isLocked());
84 >        rl.unlock();
85 >    }
86 >
87 >    /**
88 >     * locking an unlocked fair lock succeeds
89 >     */
90 >    public void testFairLock() {
91 >        ReentrantLock rl = new ReentrantLock(true);
92 >        rl.lock();
93 >        assertTrue(rl.isLocked());
94 >        rl.unlock();
95 >    }
96 >
97 >    /**
98       * Unlocking an unlocked lock throws IllegalMonitorStateException
99       */
100 <    public void testIllegalMonitorStateException(){
100 >    public void testUnlock_IllegalMonitorStateException() {
101          ReentrantLock rl = new ReentrantLock();
102 <        try{
102 >        try {
103              rl.unlock();
104 <            fail("Should of thown Illegal Monitor State Exception");
104 >            shouldThrow();
105  
106          } catch(IllegalMonitorStateException success){}
107      }
108  
109 <    /*
110 <     * lockInterruptibly is interruptible.
109 >    /**
110 >     * tryLock on an unlocked lock succeeds
111 >     */
112 >    public void testTryLock() {
113 >        ReentrantLock rl = new ReentrantLock();
114 >        assertTrue(rl.tryLock());
115 >        assertTrue(rl.isLocked());
116 >        rl.unlock();
117 >    }
118 >
119 >
120 >    /**
121 >     * hasQueuedThreads reports whether there are waiting threads
122       */
123 <    public void testInterruptedException(){
123 >    public void testhasQueuedThreads() {
124          final ReentrantLock lock = new ReentrantLock();
125 <        lock.lock();
126 <        Thread t = new Thread(new InterruptedLockRunnable(lock));
125 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
126 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
127          try {
128 <            t.start();
129 <            t.interrupt();
128 >            assertFalse(lock.hasQueuedThreads());
129 >            lock.lock();
130 >            t1.start();
131 >            Thread.sleep(SHORT_DELAY_MS);
132 >            assertTrue(lock.hasQueuedThreads());
133 >            t2.start();
134 >            Thread.sleep(SHORT_DELAY_MS);
135 >            assertTrue(lock.hasQueuedThreads());
136 >            t1.interrupt();
137 >            Thread.sleep(SHORT_DELAY_MS);
138 >            assertTrue(lock.hasQueuedThreads());
139              lock.unlock();
140 <            t.join();
140 >            Thread.sleep(SHORT_DELAY_MS);
141 >            assertFalse(lock.hasQueuedThreads());
142 >            t1.join();
143 >            t2.join();
144          } catch(Exception e){
145 <            fail("unexpected exception");
145 >            unexpectedException();
146          }
147      }
148  
149 <    /*
150 <     * getLockQueueLength reports number of waiting threads
149 >    /**
150 >     * getQueueLength reports number of waiting threads
151       */
152 <    public void testgetLockQueueLength(){
152 >    public void testGetQueueLength() {
153          final ReentrantLock lock = new ReentrantLock();
154          Thread t1 = new Thread(new InterruptedLockRunnable(lock));
155          Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
156          try {
157 <            assertEquals(0, lock.getLockQueueLength());
157 >            assertEquals(0, lock.getQueueLength());
158 >            lock.lock();
159 >            t1.start();
160 >            Thread.sleep(SHORT_DELAY_MS);
161 >            assertEquals(1, lock.getQueueLength());
162 >            t2.start();
163 >            Thread.sleep(SHORT_DELAY_MS);
164 >            assertEquals(2, lock.getQueueLength());
165 >            t1.interrupt();
166 >            Thread.sleep(SHORT_DELAY_MS);
167 >            assertEquals(1, lock.getQueueLength());
168 >            lock.unlock();
169 >            Thread.sleep(SHORT_DELAY_MS);
170 >            assertEquals(0, lock.getQueueLength());
171 >            t1.join();
172 >            t2.join();
173 >        } catch(Exception e){
174 >            unexpectedException();
175 >        }
176 >    }
177 >
178 >    /**
179 >     * getQueueLength reports number of waiting threads
180 >     */
181 >    public void testGetQueueLength_fair() {
182 >        final ReentrantLock lock = new ReentrantLock(true);
183 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
184 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
185 >        try {
186 >            assertEquals(0, lock.getQueueLength());
187              lock.lock();
188              t1.start();
189              Thread.sleep(SHORT_DELAY_MS);
190 <            assertEquals(1, lock.getLockQueueLength());
190 >            assertEquals(1, lock.getQueueLength());
191              t2.start();
192              Thread.sleep(SHORT_DELAY_MS);
193 <            assertEquals(2, lock.getLockQueueLength());
193 >            assertEquals(2, lock.getQueueLength());
194              t1.interrupt();
195              Thread.sleep(SHORT_DELAY_MS);
196 <            assertEquals(1, lock.getLockQueueLength());
196 >            assertEquals(1, lock.getQueueLength());
197              lock.unlock();
198              Thread.sleep(SHORT_DELAY_MS);
199 <            assertEquals(0, lock.getLockQueueLength());
199 >            assertEquals(0, lock.getQueueLength());
200 >            t1.join();
201 >            t2.join();
202 >        } catch(Exception e){
203 >            unexpectedException();
204 >        }
205 >    }
206 >
207 >    /**
208 >     * hasQueuedThread(null) throws NPE
209 >     */
210 >    public void testHasQueuedThreadNPE() {
211 >        final ReentrantLock sync = new ReentrantLock();
212 >        try {
213 >            sync.hasQueuedThread(null);
214 >            shouldThrow();
215 >        } catch (NullPointerException success) {
216 >        }
217 >    }
218 >
219 >    /**
220 >     * hasQueuedThread reports whether a thread is queued.
221 >     */
222 >    public void testHasQueuedThread() {
223 >        final ReentrantLock sync = new ReentrantLock();
224 >        Thread t1 = new Thread(new InterruptedLockRunnable(sync));
225 >        Thread t2 = new Thread(new InterruptibleLockRunnable(sync));
226 >        try {
227 >            assertFalse(sync.hasQueuedThread(t1));
228 >            assertFalse(sync.hasQueuedThread(t2));
229 >            sync.lock();
230 >            t1.start();
231 >            Thread.sleep(SHORT_DELAY_MS);
232 >            assertTrue(sync.hasQueuedThread(t1));
233 >            t2.start();
234 >            Thread.sleep(SHORT_DELAY_MS);
235 >            assertTrue(sync.hasQueuedThread(t1));
236 >            assertTrue(sync.hasQueuedThread(t2));
237 >            t1.interrupt();
238 >            Thread.sleep(SHORT_DELAY_MS);
239 >            assertFalse(sync.hasQueuedThread(t1));
240 >            assertTrue(sync.hasQueuedThread(t2));
241 >            sync.unlock();
242 >            Thread.sleep(SHORT_DELAY_MS);
243 >            assertFalse(sync.hasQueuedThread(t1));
244 >            Thread.sleep(SHORT_DELAY_MS);
245 >            assertFalse(sync.hasQueuedThread(t2));
246              t1.join();
247              t2.join();
248          } catch(Exception e){
249 <            fail("unexpected exception");
249 >            unexpectedException();
250          }
251      }
252  
253 <    /*
253 >
254 >    /**
255       * getQueuedThreads includes waiting threads
256       */
257 <    public void testGetQueuedThreads(){
258 <        final MyReentrantLock lock = new MyReentrantLock();
257 >    public void testGetQueuedThreads() {
258 >        final PublicReentrantLock lock = new PublicReentrantLock();
259          Thread t1 = new Thread(new InterruptedLockRunnable(lock));
260          Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
261          try {
# Line 150 | Line 279 | public class ReentrantLockTest extends J
279              t1.join();
280              t2.join();
281          } catch(Exception e){
282 <            fail("unexpected exception");
282 >            unexpectedException();
283          }
284      }
285  
286  
287 <    /*
288 <     * timed trylock is interruptible.
287 >    /**
288 >     * timed tryLock is interruptible.
289       */
290 <    public void testInterruptedException2(){
290 >    public void testInterruptedException2() {
291          final ReentrantLock lock = new ReentrantLock();
292          lock.lock();
293          Thread t = new Thread(new Runnable() {
294 <                public void run(){
295 <                    try{
294 >                public void run() {
295 >                    try {
296                          lock.tryLock(MEDIUM_DELAY_MS,TimeUnit.MILLISECONDS);
297 <                        threadFail("should throw");
297 >                        threadShouldThrow();
298                      } catch(InterruptedException success){}
299                  }
300              });
# Line 173 | Line 302 | public class ReentrantLockTest extends J
302              t.start();
303              t.interrupt();
304          } catch(Exception e){
305 <            fail("unexpected exception");
305 >            unexpectedException();
306          }
307      }
308  
309  
310      /**
311 <     * Trylock on a locked lock fails
311 >     * TryLock on a locked lock fails
312       */
313      public void testTryLockWhenLocked() {
314          final ReentrantLock lock = new ReentrantLock();
315          lock.lock();
316          Thread t = new Thread(new Runnable() {
317 <                public void run(){
317 >                public void run() {
318                      threadAssertFalse(lock.tryLock());
319                  }
320              });
# Line 194 | Line 323 | public class ReentrantLockTest extends J
323              t.join();
324              lock.unlock();
325          } catch(Exception e){
326 <            fail("unexpected exception");
326 >            unexpectedException();
327          }
328      }
329  
330      /**
331 <     * Timed Trylock on a locked lock times out
331 >     * Timed tryLock on a locked lock times out
332       */
333 <    public void testTryLock_Timeout(){
333 >    public void testTryLock_Timeout() {
334          final ReentrantLock lock = new ReentrantLock();
335          lock.lock();
336          Thread t = new Thread(new Runnable() {
337 <                public void run(){
337 >                public void run() {
338                      try {
339                          threadAssertFalse(lock.tryLock(1, TimeUnit.MILLISECONDS));
340                      } catch (Exception ex) {
341 <                        threadFail("unexpected exception");
341 >                        threadUnexpectedException();
342                      }
343                  }
344              });
# Line 218 | Line 347 | public class ReentrantLockTest extends J
347              t.join();
348              lock.unlock();
349          } catch(Exception e){
350 <            fail("unexpected exception");
350 >            unexpectedException();
351          }
352      }
353      
# Line 227 | Line 356 | public class ReentrantLockTest extends J
356       */
357      public void testGetHoldCount() {
358          ReentrantLock lock = new ReentrantLock();
359 <        for(int i = 1; i <= ReentrantLockTest.HOLD_COUNT_TEST_LIMIT;i++) {
359 >        for(int i = 1; i <= SIZE; i++) {
360              lock.lock();
361              assertEquals(i,lock.getHoldCount());
362          }
363 <        for(int i = ReentrantLockTest.HOLD_COUNT_TEST_LIMIT; i > 0; i--) {
363 >        for(int i = SIZE; i > 0; i--) {
364              lock.unlock();
365              assertEquals(i-1,lock.getHoldCount());
366          }
# Line 254 | Line 383 | public class ReentrantLockTest extends J
383                          Thread.sleep(SMALL_DELAY_MS);
384                      }
385                      catch(Exception e) {
386 <                        threadFail("unexpected exception");
386 >                        threadUnexpectedException();
387                      }
388                      lock.unlock();
389                  }
390              });
391 <        try{
391 >        try {
392              t.start();
393              Thread.sleep(SHORT_DELAY_MS);
394              assertTrue(lock.isLocked());
395              t.join();
396              assertFalse(lock.isLocked());
397          } catch(Exception e){
398 <            fail("unexpected exception");
398 >            unexpectedException();
399          }
400      }
401  
402  
403      /**
404 +     * lockInterruptibly is interruptible.
405 +     */
406 +    public void testLockInterruptibly1() {
407 +        final ReentrantLock lock = new ReentrantLock();
408 +        lock.lock();
409 +        Thread t = new Thread(new InterruptedLockRunnable(lock));
410 +        try {
411 +            t.start();
412 +            Thread.sleep(SHORT_DELAY_MS);
413 +            t.interrupt();
414 +            Thread.sleep(SHORT_DELAY_MS);
415 +            lock.unlock();
416 +            t.join();
417 +        } catch(Exception e){
418 +            unexpectedException();
419 +        }
420 +    }
421 +
422 +    /**
423       * lockInterruptibly succeeds when unlocked, else is interruptible
424       */
425 <    public void testLockInterruptibly() {
425 >    public void testLockInterruptibly2() {
426          final ReentrantLock lock = new ReentrantLock();
427          try {
428              lock.lockInterruptibly();
429          } catch(Exception e) {
430 <            fail("unexpected exception");
430 >            unexpectedException();
431          }
432          Thread t = new Thread(new InterruptedLockRunnable(lock));
433          try {
# Line 289 | Line 437 | public class ReentrantLockTest extends J
437              assertTrue(lock.isHeldByCurrentThread());
438              t.join();
439          } catch(Exception e){
440 <            fail("unexpected exception");
440 >            unexpectedException();
441          }
442      }
443  
444 +    /**
445 +     * Calling await without holding lock throws IllegalMonitorStateException
446 +     */
447      public void testAwait_IllegalMonitor() {
448          final ReentrantLock lock = new ReentrantLock();
449          final Condition c = lock.newCondition();
450          try {
451              c.await();
452 <            fail("should throw");
452 >            shouldThrow();
453          }
454          catch (IllegalMonitorStateException success) {
455          }
456          catch (Exception ex) {
457 <            fail("should throw IMSE");
457 >            unexpectedException();
458          }
459      }
460  
461 +    /**
462 +     * Calling signal without holding lock throws IllegalMonitorStateException
463 +     */
464      public void testSignal_IllegalMonitor() {
465          final ReentrantLock lock = new ReentrantLock();
466          final Condition c = lock.newCondition();
467          try {
468              c.signal();
469 <            fail("should throw");
469 >            shouldThrow();
470          }
471          catch (IllegalMonitorStateException success) {
472          }
473          catch (Exception ex) {
474 <            fail("should throw IMSE");
474 >            unexpectedException();
475          }
476      }
477  
478 +    /**
479 +     * awaitNanos without a signal times out
480 +     */
481      public void testAwaitNanos_Timeout() {
482          final ReentrantLock lock = new ReentrantLock();
483          final Condition c = lock.newCondition();
# Line 331 | Line 488 | public class ReentrantLockTest extends J
488              lock.unlock();
489          }
490          catch (Exception ex) {
491 <            fail("unexpected exception");
491 >            unexpectedException();
492          }
493      }
494  
495 +    /**
496 +     *  timed await without a signal times out
497 +     */
498      public void testAwait_Timeout() {
499          final ReentrantLock lock = new ReentrantLock();
500          final Condition c = lock.newCondition();
501          try {
502              lock.lock();
503 <            assertFalse(c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
503 >            c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
504              lock.unlock();
505          }
506          catch (Exception ex) {
507 <            fail("unexpected exception");
507 >            unexpectedException();
508          }
509      }
510  
511 +    /**
512 +     * awaitUntil without a signal times out
513 +     */
514      public void testAwaitUntil_Timeout() {
515          final ReentrantLock lock = new ReentrantLock();
516          final Condition c = lock.newCondition();
517          try {
518              lock.lock();
519              java.util.Date d = new java.util.Date();
520 <            assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
520 >            c.awaitUntil(new java.util.Date(d.getTime() + 10));
521              lock.unlock();
522          }
523          catch (Exception ex) {
524 <            fail("unexpected exception");
524 >            unexpectedException();
525          }
526      }
527  
528 +    /**
529 +     * await returns when signalled
530 +     */
531      public void testAwait() {
532          final ReentrantLock lock = new ReentrantLock();
533 <        final ReentrantLock.ConditionObject c = lock.newCondition();
533 >        final Condition c = lock.newCondition();
534          Thread t = new Thread(new Runnable() {
535                  public void run() {
536                      try {
# Line 373 | Line 539 | public class ReentrantLockTest extends J
539                          lock.unlock();
540                      }
541                      catch(InterruptedException e) {
542 <                        threadFail("unexpected exception");
542 >                        threadUnexpectedException();
543                      }
544                  }
545              });
# Line 388 | Line 554 | public class ReentrantLockTest extends J
554              assertFalse(t.isAlive());
555          }
556          catch (Exception ex) {
557 <            fail("unexpected exception");
557 >            unexpectedException();
558          }
559      }
560  
561 +    /**
562 +     * hasWaiters throws NPE if null
563 +     */
564 +    public void testHasWaitersNPE() {
565 +        final ReentrantLock lock = new ReentrantLock();
566 +        try {
567 +            lock.hasWaiters(null);
568 +            shouldThrow();
569 +        } catch (NullPointerException success) {
570 +        } catch (Exception ex) {
571 +            unexpectedException();
572 +        }
573 +    }
574 +
575 +    /**
576 +     * getWaitQueueLength throws NPE if null
577 +     */
578 +    public void testGetWaitQueueLengthNPE() {
579 +        final ReentrantLock lock = new ReentrantLock();
580 +        try {
581 +            lock.getWaitQueueLength(null);
582 +            shouldThrow();
583 +        } catch (NullPointerException success) {
584 +        } catch (Exception ex) {
585 +            unexpectedException();
586 +        }
587 +    }
588 +
589 +
590 +    /**
591 +     * getWaitingThreads throws NPE if null
592 +     */
593 +    public void testGetWaitingThreadsNPE() {
594 +        final PublicReentrantLock lock = new PublicReentrantLock();
595 +        try {
596 +            lock.getWaitingThreads(null);
597 +            shouldThrow();
598 +        } catch (NullPointerException success) {
599 +        } catch (Exception ex) {
600 +            unexpectedException();
601 +        }
602 +    }
603 +
604 +
605 +    /**
606 +     * hasWaiters throws IAE if not owned
607 +     */
608 +    public void testHasWaitersIAE() {
609 +        final ReentrantLock lock = new ReentrantLock();
610 +        final Condition c = (lock.newCondition());
611 +        final ReentrantLock lock2 = new ReentrantLock();
612 +        try {
613 +            lock2.hasWaiters(c);
614 +            shouldThrow();
615 +        } catch (IllegalArgumentException success) {
616 +        } catch (Exception ex) {
617 +            unexpectedException();
618 +        }
619 +    }
620 +
621 +    /**
622 +     * hasWaiters throws IMSE if not locked
623 +     */
624 +    public void testHasWaitersIMSE() {
625 +        final ReentrantLock lock = new ReentrantLock();
626 +        final Condition c = (lock.newCondition());
627 +        try {
628 +            lock.hasWaiters(c);
629 +            shouldThrow();
630 +        } catch (IllegalMonitorStateException success) {
631 +        } catch (Exception ex) {
632 +            unexpectedException();
633 +        }
634 +    }
635 +
636 +
637 +    /**
638 +     * getWaitQueueLength throws IAE if not owned
639 +     */
640 +    public void testGetWaitQueueLengthIAE() {
641 +        final ReentrantLock lock = new ReentrantLock();
642 +        final Condition c = (lock.newCondition());
643 +        final ReentrantLock lock2 = new ReentrantLock();
644 +        try {
645 +            lock2.getWaitQueueLength(c);
646 +            shouldThrow();
647 +        } catch (IllegalArgumentException success) {
648 +        } catch (Exception ex) {
649 +            unexpectedException();
650 +        }
651 +    }
652 +
653 +    /**
654 +     * getWaitQueueLength throws IMSE if not locked
655 +     */
656 +    public void testGetWaitQueueLengthIMSE() {
657 +        final ReentrantLock lock = new ReentrantLock();
658 +        final Condition c = (lock.newCondition());
659 +        try {
660 +            lock.getWaitQueueLength(c);
661 +            shouldThrow();
662 +        } catch (IllegalMonitorStateException success) {
663 +        } catch (Exception ex) {
664 +            unexpectedException();
665 +        }
666 +    }
667 +
668 +
669 +    /**
670 +     * getWaitingThreads throws IAE if not owned
671 +     */
672 +    public void testGetWaitingThreadsIAE() {
673 +        final PublicReentrantLock lock = new PublicReentrantLock();    
674 +        final Condition c = (lock.newCondition());
675 +        final PublicReentrantLock lock2 = new PublicReentrantLock();    
676 +        try {
677 +            lock2.getWaitingThreads(c);
678 +            shouldThrow();
679 +        } catch (IllegalArgumentException success) {
680 +        } catch (Exception ex) {
681 +            unexpectedException();
682 +        }
683 +    }
684 +
685 +    /**
686 +     * getWaitingThreads throws IMSE if not locked
687 +     */
688 +    public void testGetWaitingThreadsIMSE() {
689 +        final PublicReentrantLock lock = new PublicReentrantLock();    
690 +        final Condition c = (lock.newCondition());
691 +        try {
692 +            lock.getWaitingThreads(c);
693 +            shouldThrow();
694 +        } catch (IllegalMonitorStateException success) {
695 +        } catch (Exception ex) {
696 +            unexpectedException();
697 +        }
698 +    }
699 +
700 +
701 +
702 +    /**
703 +     * hasWaiters returns true when a thread is waiting, else false
704 +     */
705      public void testHasWaiters() {
706          final ReentrantLock lock = new ReentrantLock();
707 <        final ReentrantLock.ConditionObject c = lock.newCondition();
707 >        final Condition c = lock.newCondition();
708          Thread t = new Thread(new Runnable() {
709                  public void run() {
710                      try {
711                          lock.lock();
712 <                        threadAssertFalse(c.hasWaiters());
713 <                        threadAssertEquals(0, c.getWaitQueueLength());
712 >                        threadAssertFalse(lock.hasWaiters(c));
713 >                        threadAssertEquals(0, lock.getWaitQueueLength(c));
714                          c.await();
715                          lock.unlock();
716                      }
717                      catch(InterruptedException e) {
718 <                        threadFail("unexpected exception");
718 >                        threadUnexpectedException();
719                      }
720                  }
721              });
# Line 414 | Line 724 | public class ReentrantLockTest extends J
724              t.start();
725              Thread.sleep(SHORT_DELAY_MS);
726              lock.lock();
727 <            assertTrue(c.hasWaiters());
728 <            assertEquals(1, c.getWaitQueueLength());
727 >            assertTrue(lock.hasWaiters(c));
728 >            assertEquals(1, lock.getWaitQueueLength(c));
729              c.signal();
730              lock.unlock();
731              Thread.sleep(SHORT_DELAY_MS);
732              lock.lock();
733 <            assertFalse(c.hasWaiters());
734 <            assertEquals(0, c.getWaitQueueLength());
733 >            assertFalse(lock.hasWaiters(c));
734 >            assertEquals(0, lock.getWaitQueueLength(c));
735              lock.unlock();
736              t.join(SHORT_DELAY_MS);
737              assertFalse(t.isAlive());
738          }
739          catch (Exception ex) {
740 <            fail("unexpected exception");
740 >            unexpectedException();
741          }
742      }
743  
744 +    /**
745 +     * getWaitQueueLength returns number of waiting threads
746 +     */
747      public void testGetWaitQueueLength() {
748          final ReentrantLock lock = new ReentrantLock();
749 <        final ReentrantLock.ConditionObject c = lock.newCondition();
749 >        final Condition c = lock.newCondition();
750          Thread t1 = new Thread(new Runnable() {
751                  public void run() {
752                      try {
753                          lock.lock();
754 <                        threadAssertFalse(c.hasWaiters());
755 <                        threadAssertEquals(0, c.getWaitQueueLength());
754 >                        threadAssertFalse(lock.hasWaiters(c));
755 >                        threadAssertEquals(0, lock.getWaitQueueLength(c));
756                          c.await();
757                          lock.unlock();
758                      }
759                      catch(InterruptedException e) {
760 <                        threadFail("unexpected exception");
760 >                        threadUnexpectedException();
761                      }
762                  }
763              });
# Line 453 | Line 766 | public class ReentrantLockTest extends J
766                  public void run() {
767                      try {
768                          lock.lock();
769 <                        threadAssertTrue(c.hasWaiters());
770 <                        threadAssertEquals(1, c.getWaitQueueLength());
769 >                        threadAssertTrue(lock.hasWaiters(c));
770 >                        threadAssertEquals(1, lock.getWaitQueueLength(c));
771                          c.await();
772                          lock.unlock();
773                      }
774                      catch(InterruptedException e) {
775 <                        threadFail("unexpected exception");
775 >                        threadUnexpectedException();
776                      }
777                  }
778              });
# Line 470 | Line 783 | public class ReentrantLockTest extends J
783              t2.start();
784              Thread.sleep(SHORT_DELAY_MS);
785              lock.lock();
786 <            assertTrue(c.hasWaiters());
787 <            assertEquals(2, c.getWaitQueueLength());
786 >            assertTrue(lock.hasWaiters(c));
787 >            assertEquals(2, lock.getWaitQueueLength(c));
788              c.signalAll();
789              lock.unlock();
790              Thread.sleep(SHORT_DELAY_MS);
791              lock.lock();
792 <            assertFalse(c.hasWaiters());
793 <            assertEquals(0, c.getWaitQueueLength());
792 >            assertFalse(lock.hasWaiters(c));
793 >            assertEquals(0, lock.getWaitQueueLength(c));
794              lock.unlock();
795              t1.join(SHORT_DELAY_MS);
796              t2.join(SHORT_DELAY_MS);
# Line 485 | Line 798 | public class ReentrantLockTest extends J
798              assertFalse(t2.isAlive());
799          }
800          catch (Exception ex) {
801 <            fail("unexpected exception");
801 >            unexpectedException();
802          }
803      }
804  
805 +    /**
806 +     * getWaitingThreads returns only and all waiting threads
807 +     */
808      public void testGetWaitingThreads() {
809 <        final MyReentrantLock lock = new MyReentrantLock();    
810 <        final MyReentrantLock.MyCondition c = (MyReentrantLock.MyCondition)lock.newCondition();
809 >        final PublicReentrantLock lock = new PublicReentrantLock();    
810 >        final Condition c = lock.newCondition();
811          Thread t1 = new Thread(new Runnable() {
812                  public void run() {
813                      try {
814                          lock.lock();
815 <                        threadAssertTrue(c.getWaitingThreads().isEmpty());
815 >                        threadAssertTrue(lock.getWaitingThreads(c).isEmpty());
816                          c.await();
817                          lock.unlock();
818                      }
819                      catch(InterruptedException e) {
820 <                        threadFail("unexpected exception");
820 >                        threadUnexpectedException();
821                      }
822                  }
823              });
# Line 510 | Line 826 | public class ReentrantLockTest extends J
826                  public void run() {
827                      try {
828                          lock.lock();
829 <                        threadAssertFalse(c.getWaitingThreads().isEmpty());
829 >                        threadAssertFalse(lock.getWaitingThreads(c).isEmpty());
830                          c.await();
831                          lock.unlock();
832                      }
833                      catch(InterruptedException e) {
834 <                        threadFail("unexpected exception");
834 >                        threadUnexpectedException();
835                      }
836                  }
837              });
838  
839          try {
840              lock.lock();
841 <            assertTrue(c.getWaitingThreads().isEmpty());
841 >            assertTrue(lock.getWaitingThreads(c).isEmpty());
842              lock.unlock();
843              t1.start();
844              Thread.sleep(SHORT_DELAY_MS);
845              t2.start();
846              Thread.sleep(SHORT_DELAY_MS);
847              lock.lock();
848 <            assertTrue(c.hasWaiters());
849 <            assertTrue(c.getWaitingThreads().contains(t1));
850 <            assertTrue(c.getWaitingThreads().contains(t2));
848 >            assertTrue(lock.hasWaiters(c));
849 >            assertTrue(lock.getWaitingThreads(c).contains(t1));
850 >            assertTrue(lock.getWaitingThreads(c).contains(t2));
851              c.signalAll();
852              lock.unlock();
853              Thread.sleep(SHORT_DELAY_MS);
854              lock.lock();
855 <            assertFalse(c.hasWaiters());
856 <            assertTrue(c.getWaitingThreads().isEmpty());
855 >            assertFalse(lock.hasWaiters(c));
856 >            assertTrue(lock.getWaitingThreads(c).isEmpty());
857              lock.unlock();
858              t1.join(SHORT_DELAY_MS);
859              t2.join(SHORT_DELAY_MS);
# Line 545 | Line 861 | public class ReentrantLockTest extends J
861              assertFalse(t2.isAlive());
862          }
863          catch (Exception ex) {
864 <            fail("unexpected exception");
864 >            unexpectedException();
865          }
866      }
867  
868 +    /** A helper class for uninterruptible wait tests */
869 +    class UninterruptableThread extends Thread {
870 +        private ReentrantLock lock;
871 +        private Condition c;
872 +        
873 +        public volatile boolean canAwake = false;
874 +        public volatile boolean interrupted = false;
875 +        public volatile boolean lockStarted = false;
876 +        
877 +        public UninterruptableThread(ReentrantLock lock, Condition c) {
878 +            this.lock = lock;
879 +            this.c = c;
880 +        }
881 +        
882 +        public synchronized void run() {
883 +            lock.lock();
884 +            lockStarted = true;
885 +            
886 +            while (!canAwake) {
887 +                c.awaitUninterruptibly();
888 +            }
889 +            
890 +            interrupted = isInterrupted();
891 +            lock.unlock();
892 +        }
893 +    }
894 +
895 +    /**
896 +     * awaitUninterruptibly doesn't abort on interrupt
897 +     */
898      public void testAwaitUninterruptibly() {
899 <        final ReentrantLock lock = new ReentrantLock();
899 >        final ReentrantLock lock = new ReentrantLock();
900          final Condition c = lock.newCondition();
901 <        Thread t = new Thread(new Runnable() {
556 <                public void run() {
557 <                    lock.lock();
558 <                    c.awaitUninterruptibly();
559 <                    lock.unlock();
560 <                }
561 <            });
901 >        UninterruptableThread thread = new UninterruptableThread(lock, c);
902  
903          try {
904 <            t.start();
905 <            Thread.sleep(SHORT_DELAY_MS);
906 <            t.interrupt();
904 >            thread.start();
905 >
906 >            while (!thread.lockStarted) {
907 >                Thread.sleep(100);
908 >            }
909 >
910              lock.lock();
911 <            c.signal();
912 <            lock.unlock();
913 <            t.join(SHORT_DELAY_MS);
914 <            assertFalse(t.isAlive());
915 <        }
916 <        catch (Exception ex) {
917 <            fail("unexpected exception");
911 >            try {
912 >                thread.interrupt();
913 >                thread.canAwake = true;
914 >                c.signal();
915 >            } finally {
916 >                lock.unlock();
917 >            }
918 >
919 >            thread.join();
920 >            assertTrue(thread.interrupted);
921 >            assertFalse(thread.isAlive());
922 >        } catch (Exception ex) {
923 >            unexpectedException();
924          }
925      }
926  
927 +    /**
928 +     * await is interruptible
929 +     */
930      public void testAwait_Interrupt() {
931          final ReentrantLock lock = new ReentrantLock();
932          final Condition c = lock.newCondition();
# Line 584 | Line 936 | public class ReentrantLockTest extends J
936                          lock.lock();
937                          c.await();
938                          lock.unlock();
939 <                        threadFail("should throw");
939 >                        threadShouldThrow();
940                      }
941                      catch(InterruptedException success) {
942                      }
# Line 599 | Line 951 | public class ReentrantLockTest extends J
951              assertFalse(t.isAlive());
952          }
953          catch (Exception ex) {
954 <            fail("unexpected exception");
954 >            unexpectedException();
955          }
956      }
957  
958 +    /**
959 +     * awaitNanos is interruptible
960 +     */
961      public void testAwaitNanos_Interrupt() {
962          final ReentrantLock lock = new ReentrantLock();
963          final Condition c = lock.newCondition();
# Line 610 | Line 965 | public class ReentrantLockTest extends J
965                  public void run() {
966                      try {
967                          lock.lock();
968 <                        c.awaitNanos(SHORT_DELAY_MS * 2 * 1000000);
968 >                        c.awaitNanos(1000 * 1000 * 1000); // 1 sec
969                          lock.unlock();
970 <                        threadFail("should throw");
970 >                        threadShouldThrow();
971                      }
972                      catch(InterruptedException success) {
973                      }
# Line 627 | Line 982 | public class ReentrantLockTest extends J
982              assertFalse(t.isAlive());
983          }
984          catch (Exception ex) {
985 <            fail("unexpected exception");
985 >            unexpectedException();
986          }
987      }
988  
989 +    /**
990 +     * awaitUntil is interruptible
991 +     */
992      public void testAwaitUntil_Interrupt() {
993          final ReentrantLock lock = new ReentrantLock();
994          final Condition c = lock.newCondition();
# Line 641 | Line 999 | public class ReentrantLockTest extends J
999                          java.util.Date d = new java.util.Date();
1000                          c.awaitUntil(new java.util.Date(d.getTime() + 10000));
1001                          lock.unlock();
1002 <                        threadFail("should throw");
1002 >                        threadShouldThrow();
1003                      }
1004                      catch(InterruptedException success) {
1005                      }
# Line 656 | Line 1014 | public class ReentrantLockTest extends J
1014              assertFalse(t.isAlive());
1015          }
1016          catch (Exception ex) {
1017 <            fail("unexpected exception");
1017 >            unexpectedException();
1018          }
1019      }
1020  
1021 +    /**
1022 +     * signalAll wakes up all threads
1023 +     */
1024      public void testSignalAll() {
1025          final ReentrantLock lock = new ReentrantLock();
1026          final Condition c = lock.newCondition();
# Line 671 | Line 1032 | public class ReentrantLockTest extends J
1032                          lock.unlock();
1033                      }
1034                      catch(InterruptedException e) {
1035 <                        threadFail("unexpected exception");
1035 >                        threadUnexpectedException();
1036                      }
1037                  }
1038              });
# Line 684 | Line 1045 | public class ReentrantLockTest extends J
1045                          lock.unlock();
1046                      }
1047                      catch(InterruptedException e) {
1048 <                        threadFail("unexpected exception");
1048 >                        threadUnexpectedException();
1049                      }
1050                  }
1051              });
# Line 702 | Line 1063 | public class ReentrantLockTest extends J
1063              assertFalse(t2.isAlive());
1064          }
1065          catch (Exception ex) {
1066 <            fail("unexpected exception");
1066 >            unexpectedException();
1067          }
1068      }
1069  
1070 +    /**
1071 +     * await after multiple reentrant locking preserves lock count
1072 +     */
1073 +    public void testAwaitLockCount() {
1074 +        final ReentrantLock lock = new ReentrantLock();
1075 +        final Condition c = lock.newCondition();
1076 +        Thread t1 = new Thread(new Runnable() {
1077 +                public void run() {
1078 +                    try {
1079 +                        lock.lock();
1080 +                        threadAssertEquals(1, lock.getHoldCount());
1081 +                        c.await();
1082 +                        threadAssertEquals(1, lock.getHoldCount());
1083 +                        lock.unlock();
1084 +                    }
1085 +                    catch(InterruptedException e) {
1086 +                        threadUnexpectedException();
1087 +                    }
1088 +                }
1089 +            });
1090 +
1091 +        Thread t2 = new Thread(new Runnable() {
1092 +                public void run() {
1093 +                    try {
1094 +                        lock.lock();
1095 +                        lock.lock();
1096 +                        threadAssertEquals(2, lock.getHoldCount());
1097 +                        c.await();
1098 +                        threadAssertEquals(2, lock.getHoldCount());
1099 +                        lock.unlock();
1100 +                        lock.unlock();
1101 +                    }
1102 +                    catch(InterruptedException e) {
1103 +                        threadUnexpectedException();
1104 +                    }
1105 +                }
1106 +            });
1107 +
1108 +        try {
1109 +            t1.start();
1110 +            t2.start();
1111 +            Thread.sleep(SHORT_DELAY_MS);
1112 +            lock.lock();
1113 +            c.signalAll();
1114 +            lock.unlock();
1115 +            t1.join(SHORT_DELAY_MS);
1116 +            t2.join(SHORT_DELAY_MS);
1117 +            assertFalse(t1.isAlive());
1118 +            assertFalse(t2.isAlive());
1119 +        }
1120 +        catch (Exception ex) {
1121 +            unexpectedException();
1122 +        }
1123 +    }
1124 +
1125 +    /**
1126 +     * A serialized lock deserializes as unlocked
1127 +     */
1128      public void testSerialization() {
1129          ReentrantLock l = new ReentrantLock();
1130          l.lock();
# Line 724 | Line 1143 | public class ReentrantLockTest extends J
1143              r.unlock();
1144          } catch(Exception e){
1145              e.printStackTrace();
1146 <            fail("unexpected exception");
1146 >            unexpectedException();
1147          }
1148      }
1149  
1150 +    /**
1151 +     * toString indicates current lock state
1152 +     */
1153 +    public void testToString() {
1154 +        ReentrantLock lock = new ReentrantLock();
1155 +        String us = lock.toString();
1156 +        assertTrue(us.indexOf("Unlocked") >= 0);
1157 +        lock.lock();
1158 +        String ls = lock.toString();
1159 +        assertTrue(ls.indexOf("Locked") >= 0);
1160 +    }
1161 +
1162   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines