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.4 by dl, Sun Sep 14 20:42:40 2003 UTC vs.
Revision 1.11 by dl, Sat Dec 27 18:27:02 2003 UTC

# Line 8 | Line 8
8   import junit.framework.*;
9   import java.util.concurrent.locks.*;
10   import java.util.concurrent.*;
11 + import java.util.*;
12   import java.io.*;
13  
14   public class ReentrantLockTest extends JSR166TestCase {
14    static int HOLD_COUNT_TEST_LIMIT = 20;
15
15      public static void main(String[] args) {
16          junit.textui.TestRunner.run (suite());  
17      }
19    
18      public static Test suite() {
19          return new TestSuite(ReentrantLockTest.class);
20      }
21  
22 <    /*
23 <     * Unlocks an unlocked lock, throws Illegal Monitor State
24 <     *
22 >    /**
23 >     * A runnable calling lockInterruptibly
24 >     */
25 >    class InterruptibleLockRunnable implements Runnable {
26 >        final ReentrantLock lock;
27 >        InterruptibleLockRunnable(ReentrantLock l) { lock = l; }
28 >        public void run() {
29 >            try {
30 >                lock.lockInterruptibly();
31 >            } catch(InterruptedException success){}
32 >        }
33 >    }
34 >
35 >
36 >    /**
37 >     * A runnable calling lockInterruptibly that expects to be
38 >     * interrupted
39 >     */
40 >    class InterruptedLockRunnable implements Runnable {
41 >        final ReentrantLock lock;
42 >        InterruptedLockRunnable(ReentrantLock l) { lock = l; }
43 >        public void run() {
44 >            try {
45 >                lock.lockInterruptibly();
46 >                threadShouldThrow();
47 >            } catch(InterruptedException success){}
48 >        }
49 >    }
50 >
51 >    /**
52 >     * Subclass to expose protected methods
53       */
54 <    public void testIllegalMonitorStateException(){
54 >    static class PublicReentrantLock extends ReentrantLock {
55 >        PublicReentrantLock() { super(); }
56 >        public Collection<Thread> getQueuedThreads() {
57 >            return super.getQueuedThreads();
58 >        }
59 >
60 >    }
61 >
62 >    /**
63 >     * Constructor sets given fairness
64 >     */
65 >    public void testConstructor() {
66          ReentrantLock rl = new ReentrantLock();
67 <        try{
68 <            rl.unlock();
69 <            fail("Should of thown Illegal Monitor State Exception");
67 >        assertFalse(rl.isFair());
68 >        ReentrantLock r2 = new ReentrantLock(true);
69 >        assertTrue(r2.isFair());
70 >    }
71  
72 <        } catch(IllegalMonitorStateException success){}
72 >    /**
73 >     * locking an unlocked lock succeeds
74 >     */
75 >    public void testLock() {
76 >        ReentrantLock rl = new ReentrantLock();
77 >        rl.lock();
78 >        assertTrue(rl.isLocked());
79 >        rl.unlock();
80 >    }
81 >
82 >    /**
83 >     * locking an unlocked fair lock succeeds
84 >     */
85 >    public void testFairLock() {
86 >        ReentrantLock rl = new ReentrantLock(true);
87 >        rl.lock();
88 >        assertTrue(rl.isLocked());
89 >        rl.unlock();
90 >    }
91  
92 +    /**
93 +     * Unlocking an unlocked lock throws IllegalMonitorStateException
94 +     */
95 +    public void testUnlock_IllegalMonitorStateException() {
96 +        ReentrantLock rl = new ReentrantLock();
97 +        try {
98 +            rl.unlock();
99 +            shouldThrow();
100  
101 +        } catch(IllegalMonitorStateException success){}
102      }
103 <    
104 <    /*
105 <     * makes a lock, locks it, tries to aquire the lock in another thread
41 <     * interrupts that thread and waits for an interrupted Exception to
42 <     * be thrown.
103 >
104 >    /**
105 >     * trylock on an unlocked lock succeeds
106       */
107 +    public void testTryLock() {
108 +        ReentrantLock rl = new ReentrantLock();
109 +        assertTrue(rl.tryLock());
110 +        assertTrue(rl.isLocked());
111 +        rl.unlock();
112 +    }
113 +
114  
115 <    public void testInterruptedException(){
115 >    /**
116 >     * getQueueLength reports number of waiting threads
117 >     */
118 >    public void testGetQueueLength() {
119          final ReentrantLock lock = new ReentrantLock();
120 <        lock.lock();
121 <        Thread t = new Thread(new Runnable() {
49 <                public void run(){
50 <                    try{
51 <                        lock.lockInterruptibly();
52 <                        threadFail("should throw");
53 <                    } catch(InterruptedException success){}
54 <                }
55 <            });
120 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
121 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
122          try {
123 <            t.start();
124 <            t.interrupt();
123 >            assertEquals(0, lock.getQueueLength());
124 >            lock.lock();
125 >            t1.start();
126 >            Thread.sleep(SHORT_DELAY_MS);
127 >            assertEquals(1, lock.getQueueLength());
128 >            t2.start();
129 >            Thread.sleep(SHORT_DELAY_MS);
130 >            assertEquals(2, lock.getQueueLength());
131 >            t1.interrupt();
132 >            Thread.sleep(SHORT_DELAY_MS);
133 >            assertEquals(1, lock.getQueueLength());
134              lock.unlock();
135 <            t.join();
135 >            Thread.sleep(SHORT_DELAY_MS);
136 >            assertEquals(0, lock.getQueueLength());
137 >            t1.join();
138 >            t2.join();
139          } catch(Exception e){
140 <            fail("unexpected exception");
140 >            unexpectedException();
141          }
142      }
143  
144 <    /*
145 <     * tests for interrupted exception on a timed wait
68 <     *
144 >    /**
145 >     * getQueuedThreads includes waiting threads
146       */
147 <    
147 >    public void testGetQueuedThreads() {
148 >        final PublicReentrantLock lock = new PublicReentrantLock();
149 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
150 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
151 >        try {
152 >            assertTrue(lock.getQueuedThreads().isEmpty());
153 >            lock.lock();
154 >            assertTrue(lock.getQueuedThreads().isEmpty());
155 >            t1.start();
156 >            Thread.sleep(SHORT_DELAY_MS);
157 >            assertTrue(lock.getQueuedThreads().contains(t1));
158 >            t2.start();
159 >            Thread.sleep(SHORT_DELAY_MS);
160 >            assertTrue(lock.getQueuedThreads().contains(t1));
161 >            assertTrue(lock.getQueuedThreads().contains(t2));
162 >            t1.interrupt();
163 >            Thread.sleep(SHORT_DELAY_MS);
164 >            assertFalse(lock.getQueuedThreads().contains(t1));
165 >            assertTrue(lock.getQueuedThreads().contains(t2));
166 >            lock.unlock();
167 >            Thread.sleep(SHORT_DELAY_MS);
168 >            assertTrue(lock.getQueuedThreads().isEmpty());
169 >            t1.join();
170 >            t2.join();
171 >        } catch(Exception e){
172 >            unexpectedException();
173 >        }
174 >    }
175  
176 <    public void testInterruptedException2(){
176 >
177 >    /**
178 >     * timed trylock is interruptible.
179 >     */
180 >    public void testInterruptedException2() {
181          final ReentrantLock lock = new ReentrantLock();
182          lock.lock();
183          Thread t = new Thread(new Runnable() {
184 <                public void run(){
185 <                    try{
184 >                public void run() {
185 >                    try {
186                          lock.tryLock(MEDIUM_DELAY_MS,TimeUnit.MILLISECONDS);
187 <                        threadFail("should throw");
187 >                        threadShouldThrow();
188                      } catch(InterruptedException success){}
189                  }
190              });
# Line 84 | Line 192 | public class ReentrantLockTest extends J
192              t.start();
193              t.interrupt();
194          } catch(Exception e){
195 <            fail("unexpected exception");
195 >            unexpectedException();
196          }
197      }
198  
199  
200 +    /**
201 +     * Trylock on a locked lock fails
202 +     */
203      public void testTryLockWhenLocked() {
204          final ReentrantLock lock = new ReentrantLock();
205          lock.lock();
206          Thread t = new Thread(new Runnable() {
207 <                public void run(){
207 >                public void run() {
208                      threadAssertFalse(lock.tryLock());
209                  }
210              });
# Line 102 | Line 213 | public class ReentrantLockTest extends J
213              t.join();
214              lock.unlock();
215          } catch(Exception e){
216 <            fail("unexpected exception");
216 >            unexpectedException();
217          }
218      }
219  
220 <    public void testTryLock_Timeout(){
220 >    /**
221 >     * Timed trylock on a locked lock times out
222 >     */
223 >    public void testTryLock_Timeout() {
224          final ReentrantLock lock = new ReentrantLock();
225          lock.lock();
226          Thread t = new Thread(new Runnable() {
227 <                public void run(){
227 >                public void run() {
228                      try {
229                          threadAssertFalse(lock.tryLock(1, TimeUnit.MILLISECONDS));
230                      } catch (Exception ex) {
231 <                        threadFail("unexpected exception");
231 >                        threadUnexpectedException();
232                      }
233                  }
234              });
# Line 123 | Line 237 | public class ReentrantLockTest extends J
237              t.join();
238              lock.unlock();
239          } catch(Exception e){
240 <            fail("unexpected exception");
240 >            unexpectedException();
241          }
242      }
243      
244 +    /**
245 +     * getHoldCount returns number of recursive holds
246 +     */
247      public void testGetHoldCount() {
248          ReentrantLock lock = new ReentrantLock();
249 <        for(int i = 1; i <= ReentrantLockTest.HOLD_COUNT_TEST_LIMIT;i++) {
249 >        for(int i = 1; i <= SIZE; i++) {
250              lock.lock();
251              assertEquals(i,lock.getHoldCount());
252          }
253 <        for(int i = ReentrantLockTest.HOLD_COUNT_TEST_LIMIT; i > 0; i--) {
253 >        for(int i = SIZE; i > 0; i--) {
254              lock.unlock();
255              assertEquals(i-1,lock.getHoldCount());
256          }
257      }
258      
259    
260 <
261 <
260 >    /**
261 >     * isLocked is true when locked and false when not
262 >     */
263      public void testIsLocked() {
264          final ReentrantLock lock = new ReentrantLock();
265          lock.lock();
# Line 155 | Line 273 | public class ReentrantLockTest extends J
273                          Thread.sleep(SMALL_DELAY_MS);
274                      }
275                      catch(Exception e) {
276 <                        threadFail("unexpected exception");
276 >                        threadUnexpectedException();
277                      }
278                      lock.unlock();
279                  }
280              });
281 <        try{
281 >        try {
282              t.start();
283              Thread.sleep(SHORT_DELAY_MS);
284              assertTrue(lock.isLocked());
285              t.join();
286              assertFalse(lock.isLocked());
287          } catch(Exception e){
288 <            fail("unexpected exception");
288 >            unexpectedException();
289          }
290      }
291  
292  
293 <    public void testLockInterruptibly() {
293 >    /**
294 >     * lockInterruptibly is interruptible.
295 >     */
296 >    public void testLockInterruptibly1() {
297 >        final ReentrantLock lock = new ReentrantLock();
298 >        lock.lock();
299 >        Thread t = new Thread(new InterruptedLockRunnable(lock));
300 >        try {
301 >            t.start();
302 >            t.interrupt();
303 >            lock.unlock();
304 >            t.join();
305 >        } catch(Exception e){
306 >            unexpectedException();
307 >        }
308 >    }
309 >
310 >    /**
311 >     * lockInterruptibly succeeds when unlocked, else is interruptible
312 >     */
313 >    public void testLockInterruptibly2() {
314          final ReentrantLock lock = new ReentrantLock();
315          try {
316              lock.lockInterruptibly();
317          } catch(Exception e) {
318 <            fail("unexpected exception");
318 >            unexpectedException();
319          }
320 <        Thread t = new Thread(new Runnable() {
183 <                public void run() {
184 <                    try {
185 <                        lock.lockInterruptibly();
186 <                        threadFail("should throw");
187 <                    }
188 <                    catch(InterruptedException e) {}
189 <                }
190 <            });
320 >        Thread t = new Thread(new InterruptedLockRunnable(lock));
321          try {
322              t.start();
323              t.interrupt();
# Line 195 | Line 325 | public class ReentrantLockTest extends J
325              assertTrue(lock.isHeldByCurrentThread());
326              t.join();
327          } catch(Exception e){
328 <            fail("unexpected exception");
328 >            unexpectedException();
329          }
330      }
331  
332 +    /**
333 +     * Calling await without holding lock throws IllegalMonitorStateException
334 +     */
335      public void testAwait_IllegalMonitor() {
336          final ReentrantLock lock = new ReentrantLock();
337          final Condition c = lock.newCondition();
338          try {
339              c.await();
340 <            fail("should throw");
340 >            shouldThrow();
341          }
342          catch (IllegalMonitorStateException success) {
343          }
344          catch (Exception ex) {
345 <            fail("should throw IMSE");
345 >            unexpectedException();
346          }
347      }
348  
349 +    /**
350 +     * Calling signal without holding lock throws IllegalMonitorStateException
351 +     */
352      public void testSignal_IllegalMonitor() {
353          final ReentrantLock lock = new ReentrantLock();
354          final Condition c = lock.newCondition();
355          try {
356              c.signal();
357 <            fail("should throw");
357 >            shouldThrow();
358          }
359          catch (IllegalMonitorStateException success) {
360          }
361          catch (Exception ex) {
362 <            fail("should throw IMSE");
362 >            unexpectedException();
363          }
364      }
365  
366 +    /**
367 +     * awaitNanos without a signal times out
368 +     */
369      public void testAwaitNanos_Timeout() {
370          final ReentrantLock lock = new ReentrantLock();
371          final Condition c = lock.newCondition();
# Line 237 | Line 376 | public class ReentrantLockTest extends J
376              lock.unlock();
377          }
378          catch (Exception ex) {
379 <            fail("unexpected exception");
379 >            unexpectedException();
380          }
381      }
382  
383 +    /**
384 +     *  timed await without a signal times out
385 +     */
386      public void testAwait_Timeout() {
387          final ReentrantLock lock = new ReentrantLock();
388          final Condition c = lock.newCondition();
# Line 250 | Line 392 | public class ReentrantLockTest extends J
392              lock.unlock();
393          }
394          catch (Exception ex) {
395 <            fail("unexpected exception");
395 >            unexpectedException();
396          }
397      }
398  
399 +    /**
400 +     * awaitUntil without a signal times out
401 +     */
402      public void testAwaitUntil_Timeout() {
403          final ReentrantLock lock = new ReentrantLock();
404          final Condition c = lock.newCondition();
# Line 264 | Line 409 | public class ReentrantLockTest extends J
409              lock.unlock();
410          }
411          catch (Exception ex) {
412 <            fail("unexpected exception");
412 >            unexpectedException();
413          }
414      }
415  
416 +    /**
417 +     * await returns when signalled
418 +     */
419      public void testAwait() {
420          final ReentrantLock lock = new ReentrantLock();
421 <        final Condition c = lock.newCondition();
421 >        final AbstractQueuedSynchronizer.ConditionObject c = lock.newCondition();
422          Thread t = new Thread(new Runnable() {
423                  public void run() {
424                      try {
# Line 279 | Line 427 | public class ReentrantLockTest extends J
427                          lock.unlock();
428                      }
429                      catch(InterruptedException e) {
430 <                        threadFail("unexpected exception");
430 >                        threadUnexpectedException();
431                      }
432                  }
433              });
# Line 294 | Line 442 | public class ReentrantLockTest extends J
442              assertFalse(t.isAlive());
443          }
444          catch (Exception ex) {
445 <            fail("unexpected exception");
445 >            unexpectedException();
446 >        }
447 >    }
448 >
449 >    /**
450 >     * hasWaiters returns true when a thread is waiting, else false
451 >     */
452 >    public void testHasWaiters() {
453 >        final ReentrantLock lock = new ReentrantLock();
454 >        final AbstractQueuedSynchronizer.ConditionObject c = lock.newCondition();
455 >        Thread t = new Thread(new Runnable() {
456 >                public void run() {
457 >                    try {
458 >                        lock.lock();
459 >                        threadAssertFalse(c.hasWaiters());
460 >                        threadAssertEquals(0, c.getWaitQueueLength());
461 >                        c.await();
462 >                        lock.unlock();
463 >                    }
464 >                    catch(InterruptedException e) {
465 >                        threadUnexpectedException();
466 >                    }
467 >                }
468 >            });
469 >
470 >        try {
471 >            t.start();
472 >            Thread.sleep(SHORT_DELAY_MS);
473 >            lock.lock();
474 >            assertTrue(c.hasWaiters());
475 >            assertEquals(1, c.getWaitQueueLength());
476 >            c.signal();
477 >            lock.unlock();
478 >            Thread.sleep(SHORT_DELAY_MS);
479 >            lock.lock();
480 >            assertFalse(c.hasWaiters());
481 >            assertEquals(0, c.getWaitQueueLength());
482 >            lock.unlock();
483 >            t.join(SHORT_DELAY_MS);
484 >            assertFalse(t.isAlive());
485 >        }
486 >        catch (Exception ex) {
487 >            unexpectedException();
488 >        }
489 >    }
490 >
491 >    /**
492 >     * getWaitQueueLength returns number of waiting threads
493 >     */
494 >    public void testGetWaitQueueLength() {
495 >        final ReentrantLock lock = new ReentrantLock();
496 >        final AbstractQueuedSynchronizer.ConditionObject c = lock.newCondition();
497 >        Thread t1 = new Thread(new Runnable() {
498 >                public void run() {
499 >                    try {
500 >                        lock.lock();
501 >                        threadAssertFalse(c.hasWaiters());
502 >                        threadAssertEquals(0, c.getWaitQueueLength());
503 >                        c.await();
504 >                        lock.unlock();
505 >                    }
506 >                    catch(InterruptedException e) {
507 >                        threadUnexpectedException();
508 >                    }
509 >                }
510 >            });
511 >
512 >        Thread t2 = new Thread(new Runnable() {
513 >                public void run() {
514 >                    try {
515 >                        lock.lock();
516 >                        threadAssertTrue(c.hasWaiters());
517 >                        threadAssertEquals(1, c.getWaitQueueLength());
518 >                        c.await();
519 >                        lock.unlock();
520 >                    }
521 >                    catch(InterruptedException e) {
522 >                        threadUnexpectedException();
523 >                    }
524 >                }
525 >            });
526 >
527 >        try {
528 >            t1.start();
529 >            Thread.sleep(SHORT_DELAY_MS);
530 >            t2.start();
531 >            Thread.sleep(SHORT_DELAY_MS);
532 >            lock.lock();
533 >            assertTrue(c.hasWaiters());
534 >            assertEquals(2, c.getWaitQueueLength());
535 >            c.signalAll();
536 >            lock.unlock();
537 >            Thread.sleep(SHORT_DELAY_MS);
538 >            lock.lock();
539 >            assertFalse(c.hasWaiters());
540 >            assertEquals(0, c.getWaitQueueLength());
541 >            lock.unlock();
542 >            t1.join(SHORT_DELAY_MS);
543 >            t2.join(SHORT_DELAY_MS);
544 >            assertFalse(t1.isAlive());
545 >            assertFalse(t2.isAlive());
546 >        }
547 >        catch (Exception ex) {
548 >            unexpectedException();
549          }
550      }
551  
552 +    /**
553 +     * awaitUninterruptibly doesn't abort on interrupt
554 +     */
555      public void testAwaitUninterruptibly() {
556          final ReentrantLock lock = new ReentrantLock();
557          final Condition c = lock.newCondition();
# Line 316 | Line 570 | public class ReentrantLockTest extends J
570              lock.lock();
571              c.signal();
572              lock.unlock();
573 +            assert(t.isInterrupted());
574              t.join(SHORT_DELAY_MS);
575              assertFalse(t.isAlive());
576          }
577          catch (Exception ex) {
578 <            fail("unexpected exception");
578 >            unexpectedException();
579          }
580      }
581  
582 +    /**
583 +     * await is interruptible
584 +     */
585      public void testAwait_Interrupt() {
586          final ReentrantLock lock = new ReentrantLock();
587          final Condition c = lock.newCondition();
# Line 333 | Line 591 | public class ReentrantLockTest extends J
591                          lock.lock();
592                          c.await();
593                          lock.unlock();
594 <                        threadFail("should throw");
594 >                        threadShouldThrow();
595                      }
596                      catch(InterruptedException success) {
597                      }
# Line 348 | Line 606 | public class ReentrantLockTest extends J
606              assertFalse(t.isAlive());
607          }
608          catch (Exception ex) {
609 <            fail("unexpected exception");
609 >            unexpectedException();
610          }
611      }
612  
613 +    /**
614 +     * awaitNanos is interruptible
615 +     */
616      public void testAwaitNanos_Interrupt() {
617          final ReentrantLock lock = new ReentrantLock();
618          final Condition c = lock.newCondition();
# Line 361 | Line 622 | public class ReentrantLockTest extends J
622                          lock.lock();
623                          c.awaitNanos(SHORT_DELAY_MS * 2 * 1000000);
624                          lock.unlock();
625 <                        threadFail("should throw");
625 >                        threadShouldThrow();
626                      }
627                      catch(InterruptedException success) {
628                      }
# Line 376 | Line 637 | public class ReentrantLockTest extends J
637              assertFalse(t.isAlive());
638          }
639          catch (Exception ex) {
640 <            fail("unexpected exception");
640 >            unexpectedException();
641          }
642      }
643  
644 +    /**
645 +     * awaitUntil is interruptible
646 +     */
647      public void testAwaitUntil_Interrupt() {
648          final ReentrantLock lock = new ReentrantLock();
649          final Condition c = lock.newCondition();
# Line 390 | Line 654 | public class ReentrantLockTest extends J
654                          java.util.Date d = new java.util.Date();
655                          c.awaitUntil(new java.util.Date(d.getTime() + 10000));
656                          lock.unlock();
657 <                        threadFail("should throw");
657 >                        threadShouldThrow();
658                      }
659                      catch(InterruptedException success) {
660                      }
# Line 405 | Line 669 | public class ReentrantLockTest extends J
669              assertFalse(t.isAlive());
670          }
671          catch (Exception ex) {
672 <            fail("unexpected exception");
672 >            unexpectedException();
673          }
674      }
675  
676 +    /**
677 +     * signalAll wakes up all threads
678 +     */
679      public void testSignalAll() {
680          final ReentrantLock lock = new ReentrantLock();
681          final Condition c = lock.newCondition();
# Line 420 | Line 687 | public class ReentrantLockTest extends J
687                          lock.unlock();
688                      }
689                      catch(InterruptedException e) {
690 <                        threadFail("unexpected exception");
690 >                        threadUnexpectedException();
691                      }
692                  }
693              });
# Line 433 | Line 700 | public class ReentrantLockTest extends J
700                          lock.unlock();
701                      }
702                      catch(InterruptedException e) {
703 <                        threadFail("unexpected exception");
703 >                        threadUnexpectedException();
704                      }
705                  }
706              });
# Line 451 | Line 718 | public class ReentrantLockTest extends J
718              assertFalse(t2.isAlive());
719          }
720          catch (Exception ex) {
721 <            fail("unexpected exception");
721 >            unexpectedException();
722          }
723      }
724  
725 +    /**
726 +     * A serialized lock deserializes as unlocked
727 +     */
728      public void testSerialization() {
729          ReentrantLock l = new ReentrantLock();
730          l.lock();
# Line 473 | Line 743 | public class ReentrantLockTest extends J
743              r.unlock();
744          } catch(Exception e){
745              e.printStackTrace();
746 <            fail("unexpected exception");
746 >            unexpectedException();
747          }
748      }
749  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines