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

Comparing jsr166/src/test/tck/AbstractQueuedSynchronizerTest.java (file contents):
Revision 1.11 by dl, Thu Jan 8 01:29:46 2004 UTC vs.
Revision 1.12 by dl, Fri Jan 9 14:45:58 2004 UTC

# Line 22 | Line 22 | public class AbstractQueuedSynchronizerT
22      }
23  
24      /**
25 <     * A simple mutex class, from the AbstractQueuedSynchronizer
26 <     * javadoc.  All tests exercise this as a sample user extension.
27 <     * Other methods/features of AbstractQueuedSynchronizerTest are
28 <     * tested implicitly in ReentrantLock, ReentrantReadWriteLock, and
29 <     * Semaphore test classes
30 <     */
31 <    static class Mutex implements Lock, java.io.Serializable {
32 <        private static class Sync extends AbstractQueuedSynchronizer {
33 <            boolean isLocked() { return getState() == 1; }
34 <
35 <            public boolean tryAcquireExclusive(int acquires) {
36 <                assert acquires == 1; // Does not use multiple acquires
37 <                return compareAndSetState(0, 1);
38 <            }
39 <            
40 <            public boolean tryReleaseExclusive(int releases) {
41 <                setState(0);
42 <                return true;
43 <            }
44 <            
45 <            public void checkConditionAccess(Thread thread) {
46 <                if (getState() == 0) throw new IllegalMonitorStateException();
47 <            }
48 <            
49 <            Condition newCondition() { return new ConditionObject(); }
50 <            
51 <            private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
52 <                s.defaultReadObject();
53 <                setState(0); // reset to unlocked state
54 <            }
55 <
56 <        }
57 <        
58 <        private final Sync sync = new Sync();
59 <        public boolean tryLock() {
60 <            return sync.tryAcquireExclusive(1);
61 <        }
25 >     * A simple mutex class, adapted from the
26 >     * AbstractQueuedSynchronizer javadoc.  Exclusive acquire tests
27 >     * exercise this as a sample user extension.  Other
28 >     * methods/features of AbstractQueuedSynchronizerTest are tested
29 >     * via other test classes, including those for ReentrantLock,
30 >     * ReentrantReadWriteLock, and Semaphore
31 >     */
32 >    static class Mutex extends AbstractQueuedSynchronizer {
33 >        public boolean isLocked() { return getState() == 1; }
34 >        
35 >        public boolean tryAcquireExclusive(int acquires) {
36 >            assertTrue(acquires == 1);
37 >            return compareAndSetState(0, 1);
38 >        }
39 >        
40 >        public boolean tryReleaseExclusive(int releases) {
41 >            setState(0);
42 >            return true;
43 >        }
44 >        
45 >        public void checkConditionAccess(Thread thread) {
46 >            if (getState() == 0) throw new IllegalMonitorStateException();
47 >        }
48 >        
49 >        public ConditionObject newCondition() { return new ConditionObject(); }
50 >        
51          public void lock() {
52 <            sync.acquireExclusiveUninterruptibly(1);
52 >            acquireExclusiveUninterruptibly(1);
53          }
54 <        public void lockInterruptibly() throws InterruptedException {
55 <            sync.acquireExclusiveInterruptibly(1);
54 >
55 >    }
56 >
57 >    
58 >    /**
59 >     * A simple latch class, to test shared mode.
60 >     */
61 >    static class BooleanLatch extends AbstractQueuedSynchronizer {
62 >        public boolean isSignalled() { return getState() != 0; }
63 >
64 >        public int tryAcquireShared(int ignore) {
65 >            return isSignalled()? 1 : -1;
66          }
67 <        public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
68 <            return sync.acquireExclusiveTimed(1, unit.toNanos(timeout));
67 >        
68 >        public boolean tryReleaseShared(int ignore) {
69 >            setState(1);
70 >            return true;
71          }
71        public void unlock() { sync.releaseExclusive(1); }
72        public Condition newCondition() { return sync.newCondition(); }
73        public boolean isLocked() { return sync.isLocked(); }
74        public boolean hasQueuedThreads() { return sync.hasQueuedThreads(); }
75        public boolean hasContended() { return sync.hasContended(); }
76        public boolean isQueued(Thread t) { return sync.isQueued(t); }
72      }
73  
74      /**
75 <     * A runnable calling lockInterruptibly
75 >     * A runnable calling acquireExclusiveInterruptibly
76       */
77      class InterruptibleLockRunnable implements Runnable {
78          final Mutex lock;
79          InterruptibleLockRunnable(Mutex l) { lock = l; }
80          public void run() {
81              try {
82 <                lock.lockInterruptibly();
82 >                lock.acquireExclusiveInterruptibly(1);
83              } catch(InterruptedException success){}
84          }
85      }
86  
87  
88      /**
89 <     * A runnable calling lockInterruptibly that expects to be
89 >     * A runnable calling acquireExclusiveInterruptibly that expects to be
90       * interrupted
91       */
92      class InterruptedLockRunnable implements Runnable {
# Line 99 | Line 94 | public class AbstractQueuedSynchronizerT
94          InterruptedLockRunnable(Mutex l) { lock = l; }
95          public void run() {
96              try {
97 <                lock.lockInterruptibly();
97 >                lock.acquireExclusiveInterruptibly(1);
98                  threadShouldThrow();
99              } catch(InterruptedException success){}
100          }
101      }
102      
103      /**
104 <     * locking an unlocked lock succeeds
104 >     * acquireExclusiveUninterruptiblying an releaseExclusiveed lock succeeds
105       */
106 <    public void testLock() {
106 >    public void testAcquireExclusiveUninterruptibly() {
107          Mutex rl = new Mutex();
108 <        rl.lock();
108 >        rl.acquireExclusiveUninterruptibly(1);
109          assertTrue(rl.isLocked());
110 <        rl.unlock();
110 >        rl.releaseExclusive(1);
111      }
112  
113      /**
114 <     * tryLock on an unlocked lock succeeds
114 >     * tryAcquireExclusive on an releaseExclusiveed lock succeeds
115       */
116 <    public void testTryLock() {
116 >    public void testTryAcquireExclusive() {
117          Mutex rl = new Mutex();
118 <        assertTrue(rl.tryLock());
118 >        assertTrue(rl.tryAcquireExclusive(1));
119          assertTrue(rl.isLocked());
120 <        rl.unlock();
120 >        rl.releaseExclusive(1);
121      }
122  
123      /**
# Line 134 | Line 129 | public class AbstractQueuedSynchronizerT
129          Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
130          try {
131              assertFalse(lock.hasQueuedThreads());
132 <            lock.lock();
132 >            lock.acquireExclusiveUninterruptibly(1);
133              t1.start();
134              Thread.sleep(SHORT_DELAY_MS);
135              assertTrue(lock.hasQueuedThreads());
# Line 144 | Line 139 | public class AbstractQueuedSynchronizerT
139              t1.interrupt();
140              Thread.sleep(SHORT_DELAY_MS);
141              assertTrue(lock.hasQueuedThreads());
142 <            lock.unlock();
142 >            lock.releaseExclusive(1);
143              Thread.sleep(SHORT_DELAY_MS);
144              assertFalse(lock.hasQueuedThreads());
145              t1.join();
# Line 176 | Line 171 | public class AbstractQueuedSynchronizerT
171          try {
172              assertFalse(lock.isQueued(t1));
173              assertFalse(lock.isQueued(t2));
174 <            lock.lock();
174 >            lock.acquireExclusiveUninterruptibly(1);
175              t1.start();
176              Thread.sleep(SHORT_DELAY_MS);
177              assertTrue(lock.isQueued(t1));
# Line 188 | Line 183 | public class AbstractQueuedSynchronizerT
183              Thread.sleep(SHORT_DELAY_MS);
184              assertFalse(lock.isQueued(t1));
185              assertTrue(lock.isQueued(t2));
186 <            lock.unlock();
186 >            lock.releaseExclusive(1);
187              Thread.sleep(SHORT_DELAY_MS);
188              assertFalse(lock.isQueued(t1));
189              assertFalse(lock.isQueued(t2));
# Line 199 | Line 194 | public class AbstractQueuedSynchronizerT
194          }
195      }
196  
197 +    /**
198 +     * getFirstQueuedThread returns first waiting thread or null is none
199 +     */
200 +    public void testGetFirstQueuedThread() {
201 +        final Mutex lock = new Mutex();
202 +        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
203 +        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
204 +        try {
205 +            assertNull(lock.getFirstQueuedThread());
206 +            lock.acquireExclusiveUninterruptibly(1);
207 +            t1.start();
208 +            Thread.sleep(SHORT_DELAY_MS);
209 +            assertEquals(t1, lock.getFirstQueuedThread());
210 +            t2.start();
211 +            Thread.sleep(SHORT_DELAY_MS);
212 +            assertEquals(t1, lock.getFirstQueuedThread());
213 +            t1.interrupt();
214 +            Thread.sleep(SHORT_DELAY_MS);
215 +            assertEquals(t2, lock.getFirstQueuedThread());
216 +            lock.releaseExclusive(1);
217 +            Thread.sleep(SHORT_DELAY_MS);
218 +            assertNull(lock.getFirstQueuedThread());
219 +            t1.join();
220 +            t2.join();
221 +        } catch(Exception e){
222 +            unexpectedException();
223 +        }
224 +    }
225 +
226  
227      /**
228 <     * hasContended reports whether there has been contention
228 >     * hasContended reports false if no thread has ever blocked, else true
229       */
230 <    public void testhasContended() {
230 >    public void testHasContended() {
231          final Mutex lock = new Mutex();
232          Thread t1 = new Thread(new InterruptedLockRunnable(lock));
233          Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
234          try {
235              assertFalse(lock.hasContended());
236 <            lock.lock();
236 >            lock.acquireExclusiveUninterruptibly(1);
237              t1.start();
238              Thread.sleep(SHORT_DELAY_MS);
239              assertTrue(lock.hasContended());
# Line 219 | Line 243 | public class AbstractQueuedSynchronizerT
243              t1.interrupt();
244              Thread.sleep(SHORT_DELAY_MS);
245              assertTrue(lock.hasContended());
246 <            lock.unlock();
246 >            lock.releaseExclusive(1);
247              Thread.sleep(SHORT_DELAY_MS);
248              assertTrue(lock.hasContended());
249              t1.join();
# Line 230 | Line 254 | public class AbstractQueuedSynchronizerT
254      }
255  
256      /**
257 <     * timed tryLock is interruptible.
257 >     * timed tryAcquireExclusive is interruptible.
258       */
259      public void testInterruptedException2() {
260          final Mutex lock = new Mutex();
261 <        lock.lock();
261 >        lock.acquireExclusiveUninterruptibly(1);
262          Thread t = new Thread(new Runnable() {
263                  public void run() {
264                      try {
265 <                        lock.tryLock(MEDIUM_DELAY_MS,TimeUnit.MILLISECONDS);
265 >                        lock.acquireExclusiveNanos(1, MEDIUM_DELAY_MS * 1000 * 1000);
266                          threadShouldThrow();
267                      } catch(InterruptedException success){}
268                  }
# Line 253 | Line 277 | public class AbstractQueuedSynchronizerT
277  
278  
279      /**
280 <     * TryLock on a locked lock fails
280 >     * TryAcquireExclusive on a locked lock fails
281       */
282 <    public void testTryLockWhenLocked() {
282 >    public void testTryAcquireExclusiveWhenLocked() {
283          final Mutex lock = new Mutex();
284 <        lock.lock();
284 >        lock.acquireExclusiveUninterruptibly(1);
285          Thread t = new Thread(new Runnable() {
286                  public void run() {
287 <                    threadAssertFalse(lock.tryLock());
287 >                    threadAssertFalse(lock.tryAcquireExclusive(1));
288                  }
289              });
290          try {
291              t.start();
292              t.join();
293 <            lock.unlock();
293 >            lock.releaseExclusive(1);
294          } catch(Exception e){
295              unexpectedException();
296          }
297      }
298  
299      /**
300 <     * Timed tryLock on a locked lock times out
300 >     * acquireExclusiveTimed on a locked lock times out
301       */
302 <    public void testTryLock_Timeout() {
302 >    public void testacquireExclusiveTimed_Timeout() {
303          final Mutex lock = new Mutex();
304 <        lock.lock();
304 >        lock.acquireExclusiveUninterruptibly(1);
305          Thread t = new Thread(new Runnable() {
306                  public void run() {
307                      try {
308 <                        threadAssertFalse(lock.tryLock(1, TimeUnit.MILLISECONDS));
308 >                        threadAssertFalse(lock.acquireExclusiveNanos(1, 1000 * 1000));
309                      } catch (Exception ex) {
310                          threadUnexpectedException();
311                      }
# Line 290 | Line 314 | public class AbstractQueuedSynchronizerT
314          try {
315              t.start();
316              t.join();
317 <            lock.unlock();
317 >            lock.releaseExclusive(1);
318          } catch(Exception e){
319              unexpectedException();
320          }
# Line 302 | Line 326 | public class AbstractQueuedSynchronizerT
326       */
327      public void testIsLocked() {
328          final Mutex lock = new Mutex();
329 <        lock.lock();
329 >        lock.acquireExclusiveUninterruptibly(1);
330          assertTrue(lock.isLocked());
331 <        lock.unlock();
331 >        lock.releaseExclusive(1);
332          assertFalse(lock.isLocked());
333          Thread t = new Thread(new Runnable() {
334                  public void run() {
335 <                    lock.lock();
335 >                    lock.acquireExclusiveUninterruptibly(1);
336                      try {
337                          Thread.sleep(SMALL_DELAY_MS);
338                      }
339                      catch(Exception e) {
340                          threadUnexpectedException();
341                      }
342 <                    lock.unlock();
342 >                    lock.releaseExclusive(1);
343                  }
344              });
345          try {
# Line 331 | Line 355 | public class AbstractQueuedSynchronizerT
355  
356  
357      /**
358 <     * lockInterruptibly is interruptible.
358 >     * acquireExclusiveInterruptibly is interruptible.
359       */
360 <    public void testLockInterruptibly1() {
360 >    public void testAcquireInterruptibly1() {
361          final Mutex lock = new Mutex();
362 <        lock.lock();
362 >        lock.acquireExclusiveUninterruptibly(1);
363          Thread t = new Thread(new InterruptedLockRunnable(lock));
364          try {
365              t.start();
366              t.interrupt();
367 <            lock.unlock();
367 >            lock.releaseExclusive(1);
368              t.join();
369          } catch(Exception e){
370              unexpectedException();
# Line 348 | Line 372 | public class AbstractQueuedSynchronizerT
372      }
373  
374      /**
375 <     * lockInterruptibly succeeds when unlocked, else is interruptible
375 >     * acquireExclusiveInterruptibly succeeds when released, else is interruptible
376       */
377 <    public void testLockInterruptibly2() {
377 >    public void testAcquireInterruptibly2() {
378          final Mutex lock = new Mutex();
379          try {
380 <            lock.lockInterruptibly();
380 >            lock.acquireExclusiveInterruptibly(1);
381          } catch(Exception e) {
382              unexpectedException();
383          }
# Line 369 | Line 393 | public class AbstractQueuedSynchronizerT
393      }
394  
395      /**
396 +     * owns is true for a condition created by lock else false
397 +     */
398 +    public void testOwns() {
399 +        final Mutex lock = new Mutex();
400 +        final AbstractQueuedSynchronizer.ConditionObject c = lock.newCondition();
401 +        final Mutex lock2 = new Mutex();
402 +        assertTrue(lock.owns(c));
403 +        assertFalse(lock2.owns(c));
404 +    }
405 +
406 +    /**
407       * Calling await without holding lock throws IllegalMonitorStateException
408       */
409      public void testAwait_IllegalMonitor() {
# Line 409 | Line 444 | public class AbstractQueuedSynchronizerT
444          final Mutex lock = new Mutex();
445          final Condition c = lock.newCondition();
446          try {
447 <            lock.lock();
447 >            lock.acquireExclusiveUninterruptibly(1);
448              long t = c.awaitNanos(100);
449              assertTrue(t <= 0);
450 <            lock.unlock();
450 >            lock.releaseExclusive(1);
451          }
452          catch (Exception ex) {
453              unexpectedException();
# Line 426 | Line 461 | public class AbstractQueuedSynchronizerT
461          final Mutex lock = new Mutex();
462          final Condition c = lock.newCondition();
463          try {
464 <            lock.lock();
464 >            lock.acquireExclusiveUninterruptibly(1);
465              assertFalse(c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
466 <            lock.unlock();
466 >            lock.releaseExclusive(1);
467          }
468          catch (Exception ex) {
469              unexpectedException();
# Line 442 | Line 477 | public class AbstractQueuedSynchronizerT
477          final Mutex lock = new Mutex();
478          final Condition c = lock.newCondition();
479          try {
480 <            lock.lock();
480 >            lock.acquireExclusiveUninterruptibly(1);
481              java.util.Date d = new java.util.Date();
482              assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
483 <            lock.unlock();
483 >            lock.releaseExclusive(1);
484          }
485          catch (Exception ex) {
486              unexpectedException();
# Line 461 | Line 496 | public class AbstractQueuedSynchronizerT
496          Thread t = new Thread(new Runnable() {
497                  public void run() {
498                      try {
499 <                        lock.lock();
499 >                        lock.acquireExclusiveUninterruptibly(1);
500                          c.await();
501 <                        lock.unlock();
501 >                        lock.releaseExclusive(1);
502                      }
503                      catch(InterruptedException e) {
504                          threadUnexpectedException();
# Line 474 | Line 509 | public class AbstractQueuedSynchronizerT
509          try {
510              t.start();
511              Thread.sleep(SHORT_DELAY_MS);
512 <            lock.lock();
512 >            lock.acquireExclusiveUninterruptibly(1);
513              c.signal();
514 <            lock.unlock();
514 >            lock.releaseExclusive(1);
515              t.join(SHORT_DELAY_MS);
516              assertFalse(t.isAlive());
517          }
# Line 484 | Line 519 | public class AbstractQueuedSynchronizerT
519              unexpectedException();
520          }
521      }
522 +
523 +
524 +    /**
525 +     * Latch isSignalled initially returns false, then true after release
526 +     */
527 +    public void testLatchIsSignalled() {
528 +        final BooleanLatch l = new BooleanLatch();
529 +        assertFalse(l.isSignalled());
530 +        l.releaseShared(0);
531 +        assertTrue(l.isSignalled());
532 +    }
533 +
534 +    /**
535 +     * release and has no effect when already signalled
536 +     */
537 +    public void testLatchBoolean() {
538 +        final BooleanLatch l = new BooleanLatch();
539 +        assertFalse(l.isSignalled());
540 +        l.releaseShared(0);
541 +        assertTrue(l.isSignalled());
542 +        l.releaseShared(0);
543 +        assertTrue(l.isSignalled());
544 +    }
545 +
546 +    /**
547 +     * acquireSharedInterruptibly returns after release, but not before
548 +     */
549 +    public void testLatchAcquireSharedInterruptibly() {
550 +        final BooleanLatch l = new BooleanLatch();
551 +
552 +        Thread t = new Thread(new Runnable() {
553 +                public void run() {
554 +                    try {
555 +                        threadAssertFalse(l.isSignalled());
556 +                        l.acquireSharedInterruptibly(0);
557 +                        threadAssertTrue(l.isSignalled());
558 +                    } catch(InterruptedException e){
559 +                        threadUnexpectedException();
560 +                    }
561 +                }
562 +            });
563 +        try {
564 +            t.start();
565 +            assertFalse(l.isSignalled());
566 +            Thread.sleep(SHORT_DELAY_MS);
567 +            l.releaseShared(0);
568 +            assertTrue(l.isSignalled());
569 +            t.join();
570 +        } catch (InterruptedException e){
571 +            unexpectedException();
572 +        }
573 +    }
574 +    
575 +
576 +    /**
577 +     * acquireSharedTimed returns after release
578 +     */
579 +    public void testLatchTimedacquireSharedInterruptibly() {
580 +        final BooleanLatch l = new BooleanLatch();
581 +
582 +        Thread t = new Thread(new Runnable() {
583 +                public void run() {
584 +                    try {
585 +                        threadAssertFalse(l.isSignalled());
586 +                        threadAssertTrue(l.acquireSharedNanos(0, MEDIUM_DELAY_MS* 1000 * 1000));
587 +                        threadAssertTrue(l.isSignalled());
588 +
589 +                    } catch(InterruptedException e){
590 +                        threadUnexpectedException();
591 +                    }
592 +                }
593 +            });
594 +        try {
595 +            t.start();
596 +            assertFalse(l.isSignalled());
597 +            Thread.sleep(SHORT_DELAY_MS);
598 +            l.releaseShared(0);
599 +            assertTrue(l.isSignalled());
600 +            t.join();
601 +        } catch (InterruptedException e){
602 +            unexpectedException();
603 +        }
604 +    }
605 +    
606 +    /**
607 +     * acquireSharedInterruptibly throws IE if interrupted before released
608 +     */
609 +    public void testLatchAcquireSharedInterruptibly_InterruptedException() {
610 +        final BooleanLatch l = new BooleanLatch();
611 +        Thread t = new Thread(new Runnable() {
612 +                public void run() {
613 +                    try {
614 +                        threadAssertFalse(l.isSignalled());
615 +                        l.acquireSharedInterruptibly(0);
616 +                        threadShouldThrow();
617 +                    } catch(InterruptedException success){}
618 +                }
619 +            });
620 +        t.start();
621 +        try {
622 +            assertFalse(l.isSignalled());
623 +            t.interrupt();
624 +            t.join();
625 +        } catch (InterruptedException e){
626 +            unexpectedException();
627 +        }
628 +    }
629 +
630 +    /**
631 +     * acquireSharedTimed throws IE if interrupted before released
632 +     */
633 +    public void testLatchTimedAwait_InterruptedException() {
634 +        final BooleanLatch l = new BooleanLatch();
635 +        Thread t = new Thread(new Runnable() {
636 +                public void run() {
637 +                    try {
638 +                        threadAssertFalse(l.isSignalled());
639 +                        l.acquireSharedNanos(0, SMALL_DELAY_MS* 1000 * 1000);
640 +                        threadShouldThrow();                        
641 +                    } catch(InterruptedException success){}
642 +                }
643 +            });
644 +        t.start();
645 +        try {
646 +            Thread.sleep(SHORT_DELAY_MS);
647 +            assertFalse(l.isSignalled());
648 +            t.interrupt();
649 +            t.join();
650 +        } catch (InterruptedException e){
651 +            unexpectedException();
652 +        }
653 +    }
654 +
655 +    /**
656 +     * acquireSharedTimed times out if not released before timeout
657 +     */
658 +    public void testLatchAwaitTimeout() {
659 +        final BooleanLatch l = new BooleanLatch();
660 +        Thread t = new Thread(new Runnable() {
661 +                public void run() {
662 +                    try {
663 +                        threadAssertFalse(l.isSignalled());
664 +                        threadAssertFalse(l.acquireSharedNanos(0, SMALL_DELAY_MS* 1000 * 1000));
665 +                    } catch(InterruptedException ie){
666 +                        threadUnexpectedException();
667 +                    }
668 +                }
669 +            });
670 +        t.start();
671 +        try {
672 +            Thread.sleep(SHORT_DELAY_MS);
673 +            assertFalse(l.isSignalled());
674 +            t.join();
675 +        } catch (InterruptedException e){
676 +            unexpectedException();
677 +        }
678 +    }
679      
680   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines