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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines