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.24 by dl, Fri Feb 24 00:03:16 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 <            fail("unexpected exception");
203 >            unexpectedException();
204          }
205      }
206  
207 <    /*
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 >            unexpectedException();
250 >        }
251 >    }
252 >
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 +            lock.unlock();
415 +            t.join();
416 +        } catch(Exception e){
417 +            unexpectedException();
418 +        }
419 +    }
420 +
421 +    /**
422       * lockInterruptibly succeeds when unlocked, else is interruptible
423       */
424 <    public void testLockInterruptibly() {
424 >    public void testLockInterruptibly2() {
425          final ReentrantLock lock = new ReentrantLock();
426          try {
427              lock.lockInterruptibly();
428          } catch(Exception e) {
429 <            fail("unexpected exception");
429 >            unexpectedException();
430          }
431          Thread t = new Thread(new InterruptedLockRunnable(lock));
432          try {
# Line 289 | Line 436 | public class ReentrantLockTest extends J
436              assertTrue(lock.isHeldByCurrentThread());
437              t.join();
438          } catch(Exception e){
439 <            fail("unexpected exception");
439 >            unexpectedException();
440          }
441      }
442  
443 +    /**
444 +     * Calling await without holding lock throws IllegalMonitorStateException
445 +     */
446      public void testAwait_IllegalMonitor() {
447          final ReentrantLock lock = new ReentrantLock();
448          final Condition c = lock.newCondition();
449          try {
450              c.await();
451 <            fail("should throw");
451 >            shouldThrow();
452          }
453          catch (IllegalMonitorStateException success) {
454          }
455          catch (Exception ex) {
456 <            fail("should throw IMSE");
456 >            unexpectedException();
457          }
458      }
459  
460 +    /**
461 +     * Calling signal without holding lock throws IllegalMonitorStateException
462 +     */
463      public void testSignal_IllegalMonitor() {
464          final ReentrantLock lock = new ReentrantLock();
465          final Condition c = lock.newCondition();
466          try {
467              c.signal();
468 <            fail("should throw");
468 >            shouldThrow();
469          }
470          catch (IllegalMonitorStateException success) {
471          }
472          catch (Exception ex) {
473 <            fail("should throw IMSE");
473 >            unexpectedException();
474          }
475      }
476  
477 +    /**
478 +     * awaitNanos without a signal times out
479 +     */
480      public void testAwaitNanos_Timeout() {
481          final ReentrantLock lock = new ReentrantLock();
482          final Condition c = lock.newCondition();
# Line 331 | Line 487 | public class ReentrantLockTest extends J
487              lock.unlock();
488          }
489          catch (Exception ex) {
490 <            fail("unexpected exception");
490 >            unexpectedException();
491          }
492      }
493  
494 +    /**
495 +     *  timed await without a signal times out
496 +     */
497      public void testAwait_Timeout() {
498          final ReentrantLock lock = new ReentrantLock();
499          final Condition c = lock.newCondition();
500          try {
501              lock.lock();
502 <            assertFalse(c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
502 >            c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
503              lock.unlock();
504          }
505          catch (Exception ex) {
506 <            fail("unexpected exception");
506 >            unexpectedException();
507          }
508      }
509  
510 +    /**
511 +     * awaitUntil without a signal times out
512 +     */
513      public void testAwaitUntil_Timeout() {
514          final ReentrantLock lock = new ReentrantLock();
515          final Condition c = lock.newCondition();
516          try {
517              lock.lock();
518              java.util.Date d = new java.util.Date();
519 <            assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
519 >            c.awaitUntil(new java.util.Date(d.getTime() + 10));
520              lock.unlock();
521          }
522          catch (Exception ex) {
523 <            fail("unexpected exception");
523 >            unexpectedException();
524          }
525      }
526  
527 +    /**
528 +     * await returns when signalled
529 +     */
530      public void testAwait() {
531          final ReentrantLock lock = new ReentrantLock();
532 <        final ReentrantLock.ConditionObject c = lock.newCondition();
532 >        final Condition c = lock.newCondition();
533          Thread t = new Thread(new Runnable() {
534                  public void run() {
535                      try {
# Line 373 | Line 538 | public class ReentrantLockTest extends J
538                          lock.unlock();
539                      }
540                      catch(InterruptedException e) {
541 <                        threadFail("unexpected exception");
541 >                        threadUnexpectedException();
542                      }
543                  }
544              });
# Line 388 | Line 553 | public class ReentrantLockTest extends J
553              assertFalse(t.isAlive());
554          }
555          catch (Exception ex) {
556 <            fail("unexpected exception");
556 >            unexpectedException();
557 >        }
558 >    }
559 >
560 >    /**
561 >     * hasWaiters throws NPE if null
562 >     */
563 >    public void testHasWaitersNPE() {
564 >        final ReentrantLock lock = new ReentrantLock();
565 >        try {
566 >            lock.hasWaiters(null);
567 >            shouldThrow();
568 >        } catch (NullPointerException success) {
569 >        } catch (Exception ex) {
570 >            unexpectedException();
571 >        }
572 >    }
573 >
574 >    /**
575 >     * getWaitQueueLength throws NPE if null
576 >     */
577 >    public void testGetWaitQueueLengthNPE() {
578 >        final ReentrantLock lock = new ReentrantLock();
579 >        try {
580 >            lock.getWaitQueueLength(null);
581 >            shouldThrow();
582 >        } catch (NullPointerException success) {
583 >        } catch (Exception ex) {
584 >            unexpectedException();
585 >        }
586 >    }
587 >
588 >
589 >    /**
590 >     * getWaitingThreads throws NPE if null
591 >     */
592 >    public void testGetWaitingThreadsNPE() {
593 >        final PublicReentrantLock lock = new PublicReentrantLock();
594 >        try {
595 >            lock.getWaitingThreads(null);
596 >            shouldThrow();
597 >        } catch (NullPointerException success) {
598 >        } catch (Exception ex) {
599 >            unexpectedException();
600 >        }
601 >    }
602 >
603 >
604 >    /**
605 >     * hasWaiters throws IAE if not owned
606 >     */
607 >    public void testHasWaitersIAE() {
608 >        final ReentrantLock lock = new ReentrantLock();
609 >        final Condition c = (lock.newCondition());
610 >        final ReentrantLock lock2 = new ReentrantLock();
611 >        try {
612 >            lock2.hasWaiters(c);
613 >            shouldThrow();
614 >        } catch (IllegalArgumentException success) {
615 >        } catch (Exception ex) {
616 >            unexpectedException();
617 >        }
618 >    }
619 >
620 >    /**
621 >     * hasWaiters throws IMSE if not locked
622 >     */
623 >    public void testHasWaitersIMSE() {
624 >        final ReentrantLock lock = new ReentrantLock();
625 >        final Condition c = (lock.newCondition());
626 >        try {
627 >            lock.hasWaiters(c);
628 >            shouldThrow();
629 >        } catch (IllegalMonitorStateException success) {
630 >        } catch (Exception ex) {
631 >            unexpectedException();
632 >        }
633 >    }
634 >
635 >
636 >    /**
637 >     * getWaitQueueLength throws IAE if not owned
638 >     */
639 >    public void testGetWaitQueueLengthIAE() {
640 >        final ReentrantLock lock = new ReentrantLock();
641 >        final Condition c = (lock.newCondition());
642 >        final ReentrantLock lock2 = new ReentrantLock();
643 >        try {
644 >            lock2.getWaitQueueLength(c);
645 >            shouldThrow();
646 >        } catch (IllegalArgumentException success) {
647 >        } catch (Exception ex) {
648 >            unexpectedException();
649 >        }
650 >    }
651 >
652 >    /**
653 >     * getWaitQueueLength throws IMSE if not locked
654 >     */
655 >    public void testGetWaitQueueLengthIMSE() {
656 >        final ReentrantLock lock = new ReentrantLock();
657 >        final Condition c = (lock.newCondition());
658 >        try {
659 >            lock.getWaitQueueLength(c);
660 >            shouldThrow();
661 >        } catch (IllegalMonitorStateException success) {
662 >        } catch (Exception ex) {
663 >            unexpectedException();
664 >        }
665 >    }
666 >
667 >
668 >    /**
669 >     * getWaitingThreads throws IAE if not owned
670 >     */
671 >    public void testGetWaitingThreadsIAE() {
672 >        final PublicReentrantLock lock = new PublicReentrantLock();    
673 >        final Condition c = (lock.newCondition());
674 >        final PublicReentrantLock lock2 = new PublicReentrantLock();    
675 >        try {
676 >            lock2.getWaitingThreads(c);
677 >            shouldThrow();
678 >        } catch (IllegalArgumentException success) {
679 >        } catch (Exception ex) {
680 >            unexpectedException();
681          }
682      }
683  
684 +    /**
685 +     * getWaitingThreads throws IMSE if not locked
686 +     */
687 +    public void testGetWaitingThreadsIMSE() {
688 +        final PublicReentrantLock lock = new PublicReentrantLock();    
689 +        final Condition c = (lock.newCondition());
690 +        try {
691 +            lock.getWaitingThreads(c);
692 +            shouldThrow();
693 +        } catch (IllegalMonitorStateException success) {
694 +        } catch (Exception ex) {
695 +            unexpectedException();
696 +        }
697 +    }
698 +
699 +
700 +
701 +    /**
702 +     * hasWaiters returns true when a thread is waiting, else false
703 +     */
704      public void testHasWaiters() {
705          final ReentrantLock lock = new ReentrantLock();
706 <        final ReentrantLock.ConditionObject c = lock.newCondition();
706 >        final Condition c = lock.newCondition();
707          Thread t = new Thread(new Runnable() {
708                  public void run() {
709                      try {
710                          lock.lock();
711 <                        threadAssertFalse(c.hasWaiters());
712 <                        threadAssertEquals(0, c.getWaitQueueLength());
711 >                        threadAssertFalse(lock.hasWaiters(c));
712 >                        threadAssertEquals(0, lock.getWaitQueueLength(c));
713                          c.await();
714                          lock.unlock();
715                      }
716                      catch(InterruptedException e) {
717 <                        threadFail("unexpected exception");
717 >                        threadUnexpectedException();
718                      }
719                  }
720              });
# Line 414 | Line 723 | public class ReentrantLockTest extends J
723              t.start();
724              Thread.sleep(SHORT_DELAY_MS);
725              lock.lock();
726 <            assertTrue(c.hasWaiters());
727 <            assertEquals(1, c.getWaitQueueLength());
726 >            assertTrue(lock.hasWaiters(c));
727 >            assertEquals(1, lock.getWaitQueueLength(c));
728              c.signal();
729              lock.unlock();
730              Thread.sleep(SHORT_DELAY_MS);
731              lock.lock();
732 <            assertFalse(c.hasWaiters());
733 <            assertEquals(0, c.getWaitQueueLength());
732 >            assertFalse(lock.hasWaiters(c));
733 >            assertEquals(0, lock.getWaitQueueLength(c));
734              lock.unlock();
735              t.join(SHORT_DELAY_MS);
736              assertFalse(t.isAlive());
737          }
738          catch (Exception ex) {
739 <            fail("unexpected exception");
739 >            unexpectedException();
740          }
741      }
742  
743 +    /**
744 +     * getWaitQueueLength returns number of waiting threads
745 +     */
746      public void testGetWaitQueueLength() {
747          final ReentrantLock lock = new ReentrantLock();
748 <        final ReentrantLock.ConditionObject c = lock.newCondition();
748 >        final Condition c = lock.newCondition();
749          Thread t1 = new Thread(new Runnable() {
750                  public void run() {
751                      try {
752                          lock.lock();
753 <                        threadAssertFalse(c.hasWaiters());
754 <                        threadAssertEquals(0, c.getWaitQueueLength());
753 >                        threadAssertFalse(lock.hasWaiters(c));
754 >                        threadAssertEquals(0, lock.getWaitQueueLength(c));
755                          c.await();
756                          lock.unlock();
757                      }
758                      catch(InterruptedException e) {
759 <                        threadFail("unexpected exception");
759 >                        threadUnexpectedException();
760                      }
761                  }
762              });
# Line 453 | Line 765 | public class ReentrantLockTest extends J
765                  public void run() {
766                      try {
767                          lock.lock();
768 <                        threadAssertTrue(c.hasWaiters());
769 <                        threadAssertEquals(1, c.getWaitQueueLength());
768 >                        threadAssertTrue(lock.hasWaiters(c));
769 >                        threadAssertEquals(1, lock.getWaitQueueLength(c));
770                          c.await();
771                          lock.unlock();
772                      }
773                      catch(InterruptedException e) {
774 <                        threadFail("unexpected exception");
774 >                        threadUnexpectedException();
775                      }
776                  }
777              });
# Line 470 | Line 782 | public class ReentrantLockTest extends J
782              t2.start();
783              Thread.sleep(SHORT_DELAY_MS);
784              lock.lock();
785 <            assertTrue(c.hasWaiters());
786 <            assertEquals(2, c.getWaitQueueLength());
785 >            assertTrue(lock.hasWaiters(c));
786 >            assertEquals(2, lock.getWaitQueueLength(c));
787              c.signalAll();
788              lock.unlock();
789              Thread.sleep(SHORT_DELAY_MS);
790              lock.lock();
791 <            assertFalse(c.hasWaiters());
792 <            assertEquals(0, c.getWaitQueueLength());
791 >            assertFalse(lock.hasWaiters(c));
792 >            assertEquals(0, lock.getWaitQueueLength(c));
793              lock.unlock();
794              t1.join(SHORT_DELAY_MS);
795              t2.join(SHORT_DELAY_MS);
# Line 485 | Line 797 | public class ReentrantLockTest extends J
797              assertFalse(t2.isAlive());
798          }
799          catch (Exception ex) {
800 <            fail("unexpected exception");
800 >            unexpectedException();
801          }
802      }
803  
804 +    /**
805 +     * getWaitingThreads returns only and all waiting threads
806 +     */
807      public void testGetWaitingThreads() {
808 <        final MyReentrantLock lock = new MyReentrantLock();    
809 <        final MyReentrantLock.MyCondition c = (MyReentrantLock.MyCondition)lock.newCondition();
808 >        final PublicReentrantLock lock = new PublicReentrantLock();    
809 >        final Condition c = lock.newCondition();
810          Thread t1 = new Thread(new Runnable() {
811                  public void run() {
812                      try {
813                          lock.lock();
814 <                        threadAssertTrue(c.getWaitingThreads().isEmpty());
814 >                        threadAssertTrue(lock.getWaitingThreads(c).isEmpty());
815                          c.await();
816                          lock.unlock();
817                      }
818                      catch(InterruptedException e) {
819 <                        threadFail("unexpected exception");
819 >                        threadUnexpectedException();
820                      }
821                  }
822              });
# Line 510 | Line 825 | public class ReentrantLockTest extends J
825                  public void run() {
826                      try {
827                          lock.lock();
828 <                        threadAssertFalse(c.getWaitingThreads().isEmpty());
828 >                        threadAssertFalse(lock.getWaitingThreads(c).isEmpty());
829                          c.await();
830                          lock.unlock();
831                      }
832                      catch(InterruptedException e) {
833 <                        threadFail("unexpected exception");
833 >                        threadUnexpectedException();
834                      }
835                  }
836              });
837  
838          try {
839              lock.lock();
840 <            assertTrue(c.getWaitingThreads().isEmpty());
840 >            assertTrue(lock.getWaitingThreads(c).isEmpty());
841              lock.unlock();
842              t1.start();
843              Thread.sleep(SHORT_DELAY_MS);
844              t2.start();
845              Thread.sleep(SHORT_DELAY_MS);
846              lock.lock();
847 <            assertTrue(c.hasWaiters());
848 <            assertTrue(c.getWaitingThreads().contains(t1));
849 <            assertTrue(c.getWaitingThreads().contains(t2));
847 >            assertTrue(lock.hasWaiters(c));
848 >            assertTrue(lock.getWaitingThreads(c).contains(t1));
849 >            assertTrue(lock.getWaitingThreads(c).contains(t2));
850              c.signalAll();
851              lock.unlock();
852              Thread.sleep(SHORT_DELAY_MS);
853              lock.lock();
854 <            assertFalse(c.hasWaiters());
855 <            assertTrue(c.getWaitingThreads().isEmpty());
854 >            assertFalse(lock.hasWaiters(c));
855 >            assertTrue(lock.getWaitingThreads(c).isEmpty());
856              lock.unlock();
857              t1.join(SHORT_DELAY_MS);
858              t2.join(SHORT_DELAY_MS);
# Line 545 | Line 860 | public class ReentrantLockTest extends J
860              assertFalse(t2.isAlive());
861          }
862          catch (Exception ex) {
863 <            fail("unexpected exception");
863 >            unexpectedException();
864          }
865      }
866  
867 +    /** A helper class for uninterruptible wait tests */
868 +    class UninterruptableThread extends Thread {
869 +        private ReentrantLock lock;
870 +        private Condition c;
871 +        
872 +        public volatile boolean canAwake = false;
873 +        public volatile boolean interrupted = false;
874 +        public volatile boolean lockStarted = false;
875 +        
876 +        public UninterruptableThread(ReentrantLock lock, Condition c) {
877 +            this.lock = lock;
878 +            this.c = c;
879 +        }
880 +        
881 +        public synchronized void run() {
882 +            lock.lock();
883 +            lockStarted = true;
884 +            
885 +            while (!canAwake) {
886 +                c.awaitUninterruptibly();
887 +            }
888 +            
889 +            interrupted = isInterrupted();
890 +            lock.unlock();
891 +        }
892 +    }
893 +
894 +    /**
895 +     * awaitUninterruptibly doesn't abort on interrupt
896 +     */
897      public void testAwaitUninterruptibly() {
898 <        final ReentrantLock lock = new ReentrantLock();
898 >        final ReentrantLock lock = new ReentrantLock();
899          final Condition c = lock.newCondition();
900 <        Thread t = new Thread(new Runnable() {
556 <                public void run() {
557 <                    lock.lock();
558 <                    c.awaitUninterruptibly();
559 <                    lock.unlock();
560 <                }
561 <            });
900 >        UninterruptableThread thread = new UninterruptableThread(lock, c);
901  
902          try {
903 <            t.start();
904 <            Thread.sleep(SHORT_DELAY_MS);
905 <            t.interrupt();
903 >            thread.start();
904 >
905 >            while (!thread.lockStarted) {
906 >                Thread.sleep(100);
907 >            }
908 >
909              lock.lock();
910 <            c.signal();
911 <            lock.unlock();
912 <            t.join(SHORT_DELAY_MS);
913 <            assertFalse(t.isAlive());
914 <        }
915 <        catch (Exception ex) {
916 <            fail("unexpected exception");
910 >            try {
911 >                thread.interrupt();
912 >                thread.canAwake = true;
913 >                c.signal();
914 >            } finally {
915 >                lock.unlock();
916 >            }
917 >
918 >            thread.join();
919 >            assertTrue(thread.interrupted);
920 >            assertFalse(thread.isAlive());
921 >        } catch (Exception ex) {
922 >            unexpectedException();
923          }
924      }
925  
926 +    /**
927 +     * await is interruptible
928 +     */
929      public void testAwait_Interrupt() {
930          final ReentrantLock lock = new ReentrantLock();
931          final Condition c = lock.newCondition();
# Line 584 | Line 935 | public class ReentrantLockTest extends J
935                          lock.lock();
936                          c.await();
937                          lock.unlock();
938 <                        threadFail("should throw");
938 >                        threadShouldThrow();
939                      }
940                      catch(InterruptedException success) {
941                      }
# Line 599 | Line 950 | public class ReentrantLockTest extends J
950              assertFalse(t.isAlive());
951          }
952          catch (Exception ex) {
953 <            fail("unexpected exception");
953 >            unexpectedException();
954          }
955      }
956  
957 +    /**
958 +     * awaitNanos is interruptible
959 +     */
960      public void testAwaitNanos_Interrupt() {
961          final ReentrantLock lock = new ReentrantLock();
962          final Condition c = lock.newCondition();
# Line 610 | Line 964 | public class ReentrantLockTest extends J
964                  public void run() {
965                      try {
966                          lock.lock();
967 <                        c.awaitNanos(SHORT_DELAY_MS * 2 * 1000000);
967 >                        c.awaitNanos(1000 * 1000 * 1000); // 1 sec
968                          lock.unlock();
969 <                        threadFail("should throw");
969 >                        threadShouldThrow();
970                      }
971                      catch(InterruptedException success) {
972                      }
# Line 627 | Line 981 | public class ReentrantLockTest extends J
981              assertFalse(t.isAlive());
982          }
983          catch (Exception ex) {
984 <            fail("unexpected exception");
984 >            unexpectedException();
985          }
986      }
987  
988 +    /**
989 +     * awaitUntil is interruptible
990 +     */
991      public void testAwaitUntil_Interrupt() {
992          final ReentrantLock lock = new ReentrantLock();
993          final Condition c = lock.newCondition();
# Line 641 | Line 998 | public class ReentrantLockTest extends J
998                          java.util.Date d = new java.util.Date();
999                          c.awaitUntil(new java.util.Date(d.getTime() + 10000));
1000                          lock.unlock();
1001 <                        threadFail("should throw");
1001 >                        threadShouldThrow();
1002                      }
1003                      catch(InterruptedException success) {
1004                      }
# Line 656 | Line 1013 | public class ReentrantLockTest extends J
1013              assertFalse(t.isAlive());
1014          }
1015          catch (Exception ex) {
1016 <            fail("unexpected exception");
1016 >            unexpectedException();
1017          }
1018      }
1019  
1020 +    /**
1021 +     * signalAll wakes up all threads
1022 +     */
1023      public void testSignalAll() {
1024          final ReentrantLock lock = new ReentrantLock();
1025          final Condition c = lock.newCondition();
# Line 671 | Line 1031 | public class ReentrantLockTest extends J
1031                          lock.unlock();
1032                      }
1033                      catch(InterruptedException e) {
1034 <                        threadFail("unexpected exception");
1034 >                        threadUnexpectedException();
1035                      }
1036                  }
1037              });
# Line 684 | Line 1044 | public class ReentrantLockTest extends J
1044                          lock.unlock();
1045                      }
1046                      catch(InterruptedException e) {
1047 <                        threadFail("unexpected exception");
1047 >                        threadUnexpectedException();
1048                      }
1049                  }
1050              });
# Line 702 | Line 1062 | public class ReentrantLockTest extends J
1062              assertFalse(t2.isAlive());
1063          }
1064          catch (Exception ex) {
1065 <            fail("unexpected exception");
1065 >            unexpectedException();
1066          }
1067      }
1068  
1069 +    /**
1070 +     * await after multiple reentrant locking preserves lock count
1071 +     */
1072 +    public void testAwaitLockCount() {
1073 +        final ReentrantLock lock = new ReentrantLock();
1074 +        final Condition c = lock.newCondition();
1075 +        Thread t1 = new Thread(new Runnable() {
1076 +                public void run() {
1077 +                    try {
1078 +                        lock.lock();
1079 +                        threadAssertEquals(1, lock.getHoldCount());
1080 +                        c.await();
1081 +                        threadAssertEquals(1, lock.getHoldCount());
1082 +                        lock.unlock();
1083 +                    }
1084 +                    catch(InterruptedException e) {
1085 +                        threadUnexpectedException();
1086 +                    }
1087 +                }
1088 +            });
1089 +
1090 +        Thread t2 = new Thread(new Runnable() {
1091 +                public void run() {
1092 +                    try {
1093 +                        lock.lock();
1094 +                        lock.lock();
1095 +                        threadAssertEquals(2, lock.getHoldCount());
1096 +                        c.await();
1097 +                        threadAssertEquals(2, lock.getHoldCount());
1098 +                        lock.unlock();
1099 +                        lock.unlock();
1100 +                    }
1101 +                    catch(InterruptedException e) {
1102 +                        threadUnexpectedException();
1103 +                    }
1104 +                }
1105 +            });
1106 +
1107 +        try {
1108 +            t1.start();
1109 +            t2.start();
1110 +            Thread.sleep(SHORT_DELAY_MS);
1111 +            lock.lock();
1112 +            c.signalAll();
1113 +            lock.unlock();
1114 +            t1.join(SHORT_DELAY_MS);
1115 +            t2.join(SHORT_DELAY_MS);
1116 +            assertFalse(t1.isAlive());
1117 +            assertFalse(t2.isAlive());
1118 +        }
1119 +        catch (Exception ex) {
1120 +            unexpectedException();
1121 +        }
1122 +    }
1123 +
1124 +    /**
1125 +     * A serialized lock deserializes as unlocked
1126 +     */
1127      public void testSerialization() {
1128          ReentrantLock l = new ReentrantLock();
1129          l.lock();
# Line 724 | Line 1142 | public class ReentrantLockTest extends J
1142              r.unlock();
1143          } catch(Exception e){
1144              e.printStackTrace();
1145 <            fail("unexpected exception");
1145 >            unexpectedException();
1146          }
1147      }
1148  
1149 +    /**
1150 +     * toString indicates current lock state
1151 +     */
1152 +    public void testToString() {
1153 +        ReentrantLock lock = new ReentrantLock();
1154 +        String us = lock.toString();
1155 +        assertTrue(us.indexOf("Unlocked") >= 0);
1156 +        lock.lock();
1157 +        String ls = lock.toString();
1158 +        assertTrue(ls.indexOf("Locked") >= 0);
1159 +    }
1160 +
1161   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines