Home | History | Annotate | Download | only in jsr166
      1 /*
      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/publicdomain/zero/1.0/
      5  * Other contributors include Andrew Wright, Jeffrey Hayes,
      6  * Pat Fisher, Mike Judd.
      7  */
      8 
      9 package jsr166;
     10 
     11 import junit.framework.*;
     12 import java.util.*;
     13 import static java.util.concurrent.TimeUnit.MILLISECONDS;
     14 import java.util.concurrent.locks.AbstractQueuedSynchronizer;
     15 import java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject;
     16 
     17 public class AbstractQueuedSynchronizerTest extends JSR166TestCase {
     18 
     19     /**
     20      * A simple mutex class, adapted from the class javadoc.  Exclusive
     21      * acquire tests exercise this as a sample user extension.  Other
     22      * methods/features of AbstractQueuedSynchronizer are tested via
     23      * other test classes, including those for ReentrantLock,
     24      * ReentrantReadWriteLock, and Semaphore.
     25      */
     26     static class Mutex extends AbstractQueuedSynchronizer {
     27         /** An eccentric value for locked synchronizer state. */
     28         static final int LOCKED = (1 << 31) | (1 << 15);
     29 
     30         static final int UNLOCKED = 0;
     31 
     32         @Override public boolean isHeldExclusively() {
     33             int state = getState();
     34             assertTrue(state == UNLOCKED || state == LOCKED);
     35             return state == LOCKED;
     36         }
     37 
     38         @Override public boolean tryAcquire(int acquires) {
     39             assertEquals(LOCKED, acquires);
     40             return compareAndSetState(UNLOCKED, LOCKED);
     41         }
     42 
     43         @Override public boolean tryRelease(int releases) {
     44             if (getState() != LOCKED) throw new IllegalMonitorStateException();
     45             assertEquals(LOCKED, releases);
     46             setState(UNLOCKED);
     47             return true;
     48         }
     49 
     50         public boolean tryAcquireNanos(long nanos) throws InterruptedException {
     51             return tryAcquireNanos(LOCKED, nanos);
     52         }
     53 
     54         public boolean tryAcquire() {
     55             return tryAcquire(LOCKED);
     56         }
     57 
     58         public boolean tryRelease() {
     59             return tryRelease(LOCKED);
     60         }
     61 
     62         public void acquire() {
     63             acquire(LOCKED);
     64         }
     65 
     66         public void acquireInterruptibly() throws InterruptedException {
     67             acquireInterruptibly(LOCKED);
     68         }
     69 
     70         public void release() {
     71             release(LOCKED);
     72         }
     73 
     74         public ConditionObject newCondition() {
     75             return new ConditionObject();
     76         }
     77     }
     78 
     79     /**
     80      * A simple latch class, to test shared mode.
     81      */
     82     static class BooleanLatch extends AbstractQueuedSynchronizer {
     83         public boolean isSignalled() { return getState() != 0; }
     84 
     85         public int tryAcquireShared(int ignore) {
     86             return isSignalled() ? 1 : -1;
     87         }
     88 
     89         public boolean tryReleaseShared(int ignore) {
     90             setState(1);
     91             return true;
     92         }
     93     }
     94 
     95     /**
     96      * A runnable calling acquireInterruptibly that does not expect to
     97      * be interrupted.
     98      */
     99     class InterruptibleSyncRunnable extends CheckedRunnable {
    100         final Mutex sync;
    101         InterruptibleSyncRunnable(Mutex sync) { this.sync = sync; }
    102         public void realRun() throws InterruptedException {
    103             sync.acquireInterruptibly();
    104         }
    105     }
    106 
    107     /**
    108      * A runnable calling acquireInterruptibly that expects to be
    109      * interrupted.
    110      */
    111     class InterruptedSyncRunnable extends CheckedInterruptedRunnable {
    112         final Mutex sync;
    113         InterruptedSyncRunnable(Mutex sync) { this.sync = sync; }
    114         public void realRun() throws InterruptedException {
    115             sync.acquireInterruptibly();
    116         }
    117     }
    118 
    119     /** A constant to clarify calls to checking methods below. */
    120     static final Thread[] NO_THREADS = new Thread[0];
    121 
    122     /**
    123      * Spin-waits until sync.isQueued(t) becomes true.
    124      */
    125     void waitForQueuedThread(AbstractQueuedSynchronizer sync, Thread t) {
    126         long startTime = System.nanoTime();
    127         while (!sync.isQueued(t)) {
    128             if (millisElapsedSince(startTime) > LONG_DELAY_MS)
    129                 throw new AssertionFailedError("timed out");
    130             Thread.yield();
    131         }
    132         assertTrue(t.isAlive());
    133     }
    134 
    135     /**
    136      * Checks that sync has exactly the given queued threads.
    137      */
    138     void assertHasQueuedThreads(AbstractQueuedSynchronizer sync,
    139                                 Thread... expected) {
    140         Collection<Thread> actual = sync.getQueuedThreads();
    141         assertEquals(expected.length > 0, sync.hasQueuedThreads());
    142         assertEquals(expected.length, sync.getQueueLength());
    143         assertEquals(expected.length, actual.size());
    144         assertEquals(expected.length == 0, actual.isEmpty());
    145         assertEquals(new HashSet<Thread>(actual),
    146                      new HashSet<Thread>(Arrays.asList(expected)));
    147     }
    148 
    149     /**
    150      * Checks that sync has exactly the given (exclusive) queued threads.
    151      */
    152     void assertHasExclusiveQueuedThreads(AbstractQueuedSynchronizer sync,
    153                                          Thread... expected) {
    154         assertHasQueuedThreads(sync, expected);
    155         assertEquals(new HashSet<Thread>(sync.getExclusiveQueuedThreads()),
    156                      new HashSet<Thread>(sync.getQueuedThreads()));
    157         assertEquals(0, sync.getSharedQueuedThreads().size());
    158         assertTrue(sync.getSharedQueuedThreads().isEmpty());
    159     }
    160 
    161     /**
    162      * Checks that sync has exactly the given (shared) queued threads.
    163      */
    164     void assertHasSharedQueuedThreads(AbstractQueuedSynchronizer sync,
    165                                       Thread... expected) {
    166         assertHasQueuedThreads(sync, expected);
    167         assertEquals(new HashSet<Thread>(sync.getSharedQueuedThreads()),
    168                      new HashSet<Thread>(sync.getQueuedThreads()));
    169         assertEquals(0, sync.getExclusiveQueuedThreads().size());
    170         assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
    171     }
    172 
    173     /**
    174      * Checks that condition c has exactly the given waiter threads,
    175      * after acquiring mutex.
    176      */
    177     void assertHasWaitersUnlocked(Mutex sync, ConditionObject c,
    178                                  Thread... threads) {
    179         sync.acquire();
    180         assertHasWaitersLocked(sync, c, threads);
    181         sync.release();
    182     }
    183 
    184     /**
    185      * Checks that condition c has exactly the given waiter threads.
    186      */
    187     void assertHasWaitersLocked(Mutex sync, ConditionObject c,
    188                                 Thread... threads) {
    189         assertEquals(threads.length > 0, sync.hasWaiters(c));
    190         assertEquals(threads.length, sync.getWaitQueueLength(c));
    191         assertEquals(threads.length == 0, sync.getWaitingThreads(c).isEmpty());
    192         assertEquals(threads.length, sync.getWaitingThreads(c).size());
    193         assertEquals(new HashSet<Thread>(sync.getWaitingThreads(c)),
    194                      new HashSet<Thread>(Arrays.asList(threads)));
    195     }
    196 
    197     enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil };
    198 
    199     /**
    200      * Awaits condition using the specified AwaitMethod.
    201      */
    202     void await(ConditionObject c, AwaitMethod awaitMethod)
    203             throws InterruptedException {
    204         long timeoutMillis = 2 * LONG_DELAY_MS;
    205         switch (awaitMethod) {
    206         case await:
    207             c.await();
    208             break;
    209         case awaitTimed:
    210             assertTrue(c.await(timeoutMillis, MILLISECONDS));
    211             break;
    212         case awaitNanos:
    213             long nanosTimeout = MILLISECONDS.toNanos(timeoutMillis);
    214             long nanosRemaining = c.awaitNanos(nanosTimeout);
    215             assertTrue(nanosRemaining > 0);
    216             break;
    217         case awaitUntil:
    218             assertTrue(c.awaitUntil(delayedDate(timeoutMillis)));
    219             break;
    220         }
    221     }
    222 
    223     /**
    224      * Checks that awaiting the given condition times out (using the
    225      * default timeout duration).
    226      */
    227     void assertAwaitTimesOut(ConditionObject c, AwaitMethod awaitMethod) {
    228         long timeoutMillis = timeoutMillis();
    229         long startTime = System.nanoTime();
    230         try {
    231             switch (awaitMethod) {
    232             case awaitTimed:
    233                 assertFalse(c.await(timeoutMillis, MILLISECONDS));
    234                 break;
    235             case awaitNanos:
    236                 long nanosTimeout = MILLISECONDS.toNanos(timeoutMillis);
    237                 long nanosRemaining = c.awaitNanos(nanosTimeout);
    238                 assertTrue(nanosRemaining <= 0);
    239                 break;
    240             case awaitUntil:
    241                 assertFalse(c.awaitUntil(delayedDate(timeoutMillis)));
    242                 break;
    243             default:
    244                 throw new UnsupportedOperationException();
    245             }
    246         } catch (InterruptedException ie) { threadUnexpectedException(ie); }
    247         assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
    248     }
    249 
    250     /**
    251      * isHeldExclusively is false upon construction
    252      */
    253     public void testIsHeldExclusively() {
    254         Mutex sync = new Mutex();
    255         assertFalse(sync.isHeldExclusively());
    256     }
    257 
    258     /**
    259      * acquiring released sync succeeds
    260      */
    261     public void testAcquire() {
    262         Mutex sync = new Mutex();
    263         sync.acquire();
    264         assertTrue(sync.isHeldExclusively());
    265         sync.release();
    266         assertFalse(sync.isHeldExclusively());
    267     }
    268 
    269     /**
    270      * tryAcquire on a released sync succeeds
    271      */
    272     public void testTryAcquire() {
    273         Mutex sync = new Mutex();
    274         assertTrue(sync.tryAcquire());
    275         assertTrue(sync.isHeldExclusively());
    276         sync.release();
    277         assertFalse(sync.isHeldExclusively());
    278     }
    279 
    280     /**
    281      * hasQueuedThreads reports whether there are waiting threads
    282      */
    283     public void testHasQueuedThreads() {
    284         final Mutex sync = new Mutex();
    285         assertFalse(sync.hasQueuedThreads());
    286         sync.acquire();
    287         Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
    288         waitForQueuedThread(sync, t1);
    289         assertTrue(sync.hasQueuedThreads());
    290         Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
    291         waitForQueuedThread(sync, t2);
    292         assertTrue(sync.hasQueuedThreads());
    293         t1.interrupt();
    294         awaitTermination(t1);
    295         assertTrue(sync.hasQueuedThreads());
    296         sync.release();
    297         awaitTermination(t2);
    298         assertFalse(sync.hasQueuedThreads());
    299     }
    300 
    301     /**
    302      * isQueued(null) throws NullPointerException
    303      */
    304     public void testIsQueuedNPE() {
    305         final Mutex sync = new Mutex();
    306         try {
    307             sync.isQueued(null);
    308             shouldThrow();
    309         } catch (NullPointerException success) {}
    310     }
    311 
    312     /**
    313      * isQueued reports whether a thread is queued
    314      */
    315     public void testIsQueued() {
    316         final Mutex sync = new Mutex();
    317         Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
    318         Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
    319         assertFalse(sync.isQueued(t1));
    320         assertFalse(sync.isQueued(t2));
    321         sync.acquire();
    322         t1.start();
    323         waitForQueuedThread(sync, t1);
    324         assertTrue(sync.isQueued(t1));
    325         assertFalse(sync.isQueued(t2));
    326         t2.start();
    327         waitForQueuedThread(sync, t2);
    328         assertTrue(sync.isQueued(t1));
    329         assertTrue(sync.isQueued(t2));
    330         t1.interrupt();
    331         awaitTermination(t1);
    332         assertFalse(sync.isQueued(t1));
    333         assertTrue(sync.isQueued(t2));
    334         sync.release();
    335         awaitTermination(t2);
    336         assertFalse(sync.isQueued(t1));
    337         assertFalse(sync.isQueued(t2));
    338     }
    339 
    340     /**
    341      * getFirstQueuedThread returns first waiting thread or null if none
    342      */
    343     public void testGetFirstQueuedThread() {
    344         final Mutex sync = new Mutex();
    345         assertNull(sync.getFirstQueuedThread());
    346         sync.acquire();
    347         Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
    348         waitForQueuedThread(sync, t1);
    349         assertEquals(t1, sync.getFirstQueuedThread());
    350         Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
    351         waitForQueuedThread(sync, t2);
    352         assertEquals(t1, sync.getFirstQueuedThread());
    353         t1.interrupt();
    354         awaitTermination(t1);
    355         assertEquals(t2, sync.getFirstQueuedThread());
    356         sync.release();
    357         awaitTermination(t2);
    358         assertNull(sync.getFirstQueuedThread());
    359     }
    360 
    361     /**
    362      * hasContended reports false if no thread has ever blocked, else true
    363      */
    364     public void testHasContended() {
    365         final Mutex sync = new Mutex();
    366         assertFalse(sync.hasContended());
    367         sync.acquire();
    368         assertFalse(sync.hasContended());
    369         Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
    370         waitForQueuedThread(sync, t1);
    371         assertTrue(sync.hasContended());
    372         Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
    373         waitForQueuedThread(sync, t2);
    374         assertTrue(sync.hasContended());
    375         t1.interrupt();
    376         awaitTermination(t1);
    377         assertTrue(sync.hasContended());
    378         sync.release();
    379         awaitTermination(t2);
    380         assertTrue(sync.hasContended());
    381     }
    382 
    383     /**
    384      * getQueuedThreads returns all waiting threads
    385      */
    386     public void testGetQueuedThreads() {
    387         final Mutex sync = new Mutex();
    388         Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
    389         Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
    390         assertHasExclusiveQueuedThreads(sync, NO_THREADS);
    391         sync.acquire();
    392         assertHasExclusiveQueuedThreads(sync, NO_THREADS);
    393         t1.start();
    394         waitForQueuedThread(sync, t1);
    395         assertHasExclusiveQueuedThreads(sync, t1);
    396         assertTrue(sync.getQueuedThreads().contains(t1));
    397         assertFalse(sync.getQueuedThreads().contains(t2));
    398         t2.start();
    399         waitForQueuedThread(sync, t2);
    400         assertHasExclusiveQueuedThreads(sync, t1, t2);
    401         assertTrue(sync.getQueuedThreads().contains(t1));
    402         assertTrue(sync.getQueuedThreads().contains(t2));
    403         t1.interrupt();
    404         awaitTermination(t1);
    405         assertHasExclusiveQueuedThreads(sync, t2);
    406         sync.release();
    407         awaitTermination(t2);
    408         assertHasExclusiveQueuedThreads(sync, NO_THREADS);
    409     }
    410 
    411     /**
    412      * getExclusiveQueuedThreads returns all exclusive waiting threads
    413      */
    414     public void testGetExclusiveQueuedThreads() {
    415         final Mutex sync = new Mutex();
    416         Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
    417         Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
    418         assertHasExclusiveQueuedThreads(sync, NO_THREADS);
    419         sync.acquire();
    420         assertHasExclusiveQueuedThreads(sync, NO_THREADS);
    421         t1.start();
    422         waitForQueuedThread(sync, t1);
    423         assertHasExclusiveQueuedThreads(sync, t1);
    424         assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
    425         assertFalse(sync.getExclusiveQueuedThreads().contains(t2));
    426         t2.start();
    427         waitForQueuedThread(sync, t2);
    428         assertHasExclusiveQueuedThreads(sync, t1, t2);
    429         assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
    430         assertTrue(sync.getExclusiveQueuedThreads().contains(t2));
    431         t1.interrupt();
    432         awaitTermination(t1);
    433         assertHasExclusiveQueuedThreads(sync, t2);
    434         sync.release();
    435         awaitTermination(t2);
    436         assertHasExclusiveQueuedThreads(sync, NO_THREADS);
    437     }
    438 
    439     /**
    440      * getSharedQueuedThreads does not include exclusively waiting threads
    441      */
    442     public void testGetSharedQueuedThreads_Exclusive() {
    443         final Mutex sync = new Mutex();
    444         assertTrue(sync.getSharedQueuedThreads().isEmpty());
    445         sync.acquire();
    446         assertTrue(sync.getSharedQueuedThreads().isEmpty());
    447         Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
    448         waitForQueuedThread(sync, t1);
    449         assertTrue(sync.getSharedQueuedThreads().isEmpty());
    450         Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
    451         waitForQueuedThread(sync, t2);
    452         assertTrue(sync.getSharedQueuedThreads().isEmpty());
    453         t1.interrupt();
    454         awaitTermination(t1);
    455         assertTrue(sync.getSharedQueuedThreads().isEmpty());
    456         sync.release();
    457         awaitTermination(t2);
    458         assertTrue(sync.getSharedQueuedThreads().isEmpty());
    459     }
    460 
    461     /**
    462      * getSharedQueuedThreads returns all shared waiting threads
    463      */
    464     public void testGetSharedQueuedThreads_Shared() {
    465         final BooleanLatch l = new BooleanLatch();
    466         assertHasSharedQueuedThreads(l, NO_THREADS);
    467         Thread t1 = newStartedThread(new CheckedInterruptedRunnable() {
    468             public void realRun() throws InterruptedException {
    469                 l.acquireSharedInterruptibly(0);
    470             }});
    471         waitForQueuedThread(l, t1);
    472         assertHasSharedQueuedThreads(l, t1);
    473         Thread t2 = newStartedThread(new CheckedRunnable() {
    474             public void realRun() throws InterruptedException {
    475                 l.acquireSharedInterruptibly(0);
    476             }});
    477         waitForQueuedThread(l, t2);
    478         assertHasSharedQueuedThreads(l, t1, t2);
    479         t1.interrupt();
    480         awaitTermination(t1);
    481         assertHasSharedQueuedThreads(l, t2);
    482         assertTrue(l.releaseShared(0));
    483         awaitTermination(t2);
    484         assertHasSharedQueuedThreads(l, NO_THREADS);
    485     }
    486 
    487     /**
    488      * tryAcquireNanos is interruptible
    489      */
    490     public void testTryAcquireNanos_Interruptible() {
    491         final Mutex sync = new Mutex();
    492         sync.acquire();
    493         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
    494             public void realRun() throws InterruptedException {
    495                 sync.tryAcquireNanos(MILLISECONDS.toNanos(2 * LONG_DELAY_MS));
    496             }});
    497 
    498         waitForQueuedThread(sync, t);
    499         t.interrupt();
    500         awaitTermination(t);
    501     }
    502 
    503     /**
    504      * tryAcquire on exclusively held sync fails
    505      */
    506     public void testTryAcquireWhenSynced() {
    507         final Mutex sync = new Mutex();
    508         sync.acquire();
    509         Thread t = newStartedThread(new CheckedRunnable() {
    510             public void realRun() {
    511                 assertFalse(sync.tryAcquire());
    512             }});
    513 
    514         awaitTermination(t);
    515         sync.release();
    516     }
    517 
    518     /**
    519      * tryAcquireNanos on an exclusively held sync times out
    520      */
    521     public void testAcquireNanos_Timeout() {
    522         final Mutex sync = new Mutex();
    523         sync.acquire();
    524         Thread t = newStartedThread(new CheckedRunnable() {
    525             public void realRun() throws InterruptedException {
    526                 long startTime = System.nanoTime();
    527                 long nanos = MILLISECONDS.toNanos(timeoutMillis());
    528                 assertFalse(sync.tryAcquireNanos(nanos));
    529                 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
    530             }});
    531 
    532         awaitTermination(t);
    533         sync.release();
    534     }
    535 
    536     /**
    537      * getState is true when acquired and false when not
    538      */
    539     public void testGetState() {
    540         final Mutex sync = new Mutex();
    541         sync.acquire();
    542         assertTrue(sync.isHeldExclusively());
    543         sync.release();
    544         assertFalse(sync.isHeldExclusively());
    545 
    546         final BooleanLatch acquired = new BooleanLatch();
    547         final BooleanLatch done = new BooleanLatch();
    548         Thread t = newStartedThread(new CheckedRunnable() {
    549             public void realRun() throws InterruptedException {
    550                 sync.acquire();
    551                 assertTrue(acquired.releaseShared(0));
    552                 done.acquireShared(0);
    553                 sync.release();
    554             }});
    555 
    556         acquired.acquireShared(0);
    557         assertTrue(sync.isHeldExclusively());
    558         assertTrue(done.releaseShared(0));
    559         awaitTermination(t);
    560         assertFalse(sync.isHeldExclusively());
    561     }
    562 
    563     /**
    564      * acquireInterruptibly succeeds when released, else is interruptible
    565      */
    566     public void testAcquireInterruptibly() throws InterruptedException {
    567         final Mutex sync = new Mutex();
    568         final BooleanLatch threadStarted = new BooleanLatch();
    569         sync.acquireInterruptibly();
    570         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
    571             public void realRun() throws InterruptedException {
    572                 assertTrue(threadStarted.releaseShared(0));
    573                 sync.acquireInterruptibly();
    574             }});
    575 
    576         threadStarted.acquireShared(0);
    577         waitForQueuedThread(sync, t);
    578         t.interrupt();
    579         awaitTermination(t);
    580         assertTrue(sync.isHeldExclusively());
    581     }
    582 
    583     /**
    584      * owns is true for a condition created by sync else false
    585      */
    586     public void testOwns() {
    587         final Mutex sync = new Mutex();
    588         final ConditionObject c = sync.newCondition();
    589         final Mutex sync2 = new Mutex();
    590         assertTrue(sync.owns(c));
    591         assertFalse(sync2.owns(c));
    592     }
    593 
    594     /**
    595      * Calling await without holding sync throws IllegalMonitorStateException
    596      */
    597     public void testAwait_IMSE() {
    598         final Mutex sync = new Mutex();
    599         final ConditionObject c = sync.newCondition();
    600         for (AwaitMethod awaitMethod : AwaitMethod.values()) {
    601             long startTime = System.nanoTime();
    602             try {
    603                 await(c, awaitMethod);
    604                 shouldThrow();
    605             } catch (IllegalMonitorStateException success) {
    606             } catch (InterruptedException e) { threadUnexpectedException(e); }
    607             assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
    608         }
    609     }
    610 
    611     /**
    612      * Calling signal without holding sync throws IllegalMonitorStateException
    613      */
    614     public void testSignal_IMSE() {
    615         final Mutex sync = new Mutex();
    616         final ConditionObject c = sync.newCondition();
    617         try {
    618             c.signal();
    619             shouldThrow();
    620         } catch (IllegalMonitorStateException success) {}
    621         assertHasWaitersUnlocked(sync, c, NO_THREADS);
    622     }
    623 
    624     /**
    625      * Calling signalAll without holding sync throws IllegalMonitorStateException
    626      */
    627     public void testSignalAll_IMSE() {
    628         final Mutex sync = new Mutex();
    629         final ConditionObject c = sync.newCondition();
    630         try {
    631             c.signalAll();
    632             shouldThrow();
    633         } catch (IllegalMonitorStateException success) {}
    634     }
    635 
    636     /**
    637      * await/awaitNanos/awaitUntil without a signal times out
    638      */
    639     public void testAwaitTimed_Timeout() { testAwait_Timeout(AwaitMethod.awaitTimed); }
    640     public void testAwaitNanos_Timeout() { testAwait_Timeout(AwaitMethod.awaitNanos); }
    641     public void testAwaitUntil_Timeout() { testAwait_Timeout(AwaitMethod.awaitUntil); }
    642     public void testAwait_Timeout(AwaitMethod awaitMethod) {
    643         final Mutex sync = new Mutex();
    644         final ConditionObject c = sync.newCondition();
    645         sync.acquire();
    646         assertAwaitTimesOut(c, awaitMethod);
    647         sync.release();
    648     }
    649 
    650     /**
    651      * await/awaitNanos/awaitUntil returns when signalled
    652      */
    653     public void testSignal_await()      { testSignal(AwaitMethod.await); }
    654     public void testSignal_awaitTimed() { testSignal(AwaitMethod.awaitTimed); }
    655     public void testSignal_awaitNanos() { testSignal(AwaitMethod.awaitNanos); }
    656     public void testSignal_awaitUntil() { testSignal(AwaitMethod.awaitUntil); }
    657     public void testSignal(final AwaitMethod awaitMethod) {
    658         final Mutex sync = new Mutex();
    659         final ConditionObject c = sync.newCondition();
    660         final BooleanLatch acquired = new BooleanLatch();
    661         Thread t = newStartedThread(new CheckedRunnable() {
    662             public void realRun() throws InterruptedException {
    663                 sync.acquire();
    664                 assertTrue(acquired.releaseShared(0));
    665                 await(c, awaitMethod);
    666                 sync.release();
    667             }});
    668 
    669         acquired.acquireShared(0);
    670         sync.acquire();
    671         assertHasWaitersLocked(sync, c, t);
    672         assertHasExclusiveQueuedThreads(sync, NO_THREADS);
    673         c.signal();
    674         assertHasWaitersLocked(sync, c, NO_THREADS);
    675         assertHasExclusiveQueuedThreads(sync, t);
    676         sync.release();
    677         awaitTermination(t);
    678     }
    679 
    680     /**
    681      * hasWaiters(null) throws NullPointerException
    682      */
    683     public void testHasWaitersNPE() {
    684         final Mutex sync = new Mutex();
    685         try {
    686             sync.hasWaiters(null);
    687             shouldThrow();
    688         } catch (NullPointerException success) {}
    689     }
    690 
    691     /**
    692      * getWaitQueueLength(null) throws NullPointerException
    693      */
    694     public void testGetWaitQueueLengthNPE() {
    695         final Mutex sync = new Mutex();
    696         try {
    697             sync.getWaitQueueLength(null);
    698             shouldThrow();
    699         } catch (NullPointerException success) {}
    700     }
    701 
    702     /**
    703      * getWaitingThreads(null) throws NullPointerException
    704      */
    705     public void testGetWaitingThreadsNPE() {
    706         final Mutex sync = new Mutex();
    707         try {
    708             sync.getWaitingThreads(null);
    709             shouldThrow();
    710         } catch (NullPointerException success) {}
    711     }
    712 
    713     /**
    714      * hasWaiters throws IllegalArgumentException if not owned
    715      */
    716     public void testHasWaitersIAE() {
    717         final Mutex sync = new Mutex();
    718         final ConditionObject c = sync.newCondition();
    719         final Mutex sync2 = new Mutex();
    720         try {
    721             sync2.hasWaiters(c);
    722             shouldThrow();
    723         } catch (IllegalArgumentException success) {}
    724         assertHasWaitersUnlocked(sync, c, NO_THREADS);
    725     }
    726 
    727     /**
    728      * hasWaiters throws IllegalMonitorStateException if not synced
    729      */
    730     public void testHasWaitersIMSE() {
    731         final Mutex sync = new Mutex();
    732         final ConditionObject c = sync.newCondition();
    733         try {
    734             sync.hasWaiters(c);
    735             shouldThrow();
    736         } catch (IllegalMonitorStateException success) {}
    737         assertHasWaitersUnlocked(sync, c, NO_THREADS);
    738     }
    739 
    740     /**
    741      * getWaitQueueLength throws IllegalArgumentException if not owned
    742      */
    743     public void testGetWaitQueueLengthIAE() {
    744         final Mutex sync = new Mutex();
    745         final ConditionObject c = sync.newCondition();
    746         final Mutex sync2 = new Mutex();
    747         try {
    748             sync2.getWaitQueueLength(c);
    749             shouldThrow();
    750         } catch (IllegalArgumentException success) {}
    751         assertHasWaitersUnlocked(sync, c, NO_THREADS);
    752     }
    753 
    754     /**
    755      * getWaitQueueLength throws IllegalMonitorStateException if not synced
    756      */
    757     public void testGetWaitQueueLengthIMSE() {
    758         final Mutex sync = new Mutex();
    759         final ConditionObject c = sync.newCondition();
    760         try {
    761             sync.getWaitQueueLength(c);
    762             shouldThrow();
    763         } catch (IllegalMonitorStateException success) {}
    764         assertHasWaitersUnlocked(sync, c, NO_THREADS);
    765     }
    766 
    767     /**
    768      * getWaitingThreads throws IllegalArgumentException if not owned
    769      */
    770     public void testGetWaitingThreadsIAE() {
    771         final Mutex sync = new Mutex();
    772         final ConditionObject c = sync.newCondition();
    773         final Mutex sync2 = new Mutex();
    774         try {
    775             sync2.getWaitingThreads(c);
    776             shouldThrow();
    777         } catch (IllegalArgumentException success) {}
    778         assertHasWaitersUnlocked(sync, c, NO_THREADS);
    779     }
    780 
    781     /**
    782      * getWaitingThreads throws IllegalMonitorStateException if not synced
    783      */
    784     public void testGetWaitingThreadsIMSE() {
    785         final Mutex sync = new Mutex();
    786         final ConditionObject c = sync.newCondition();
    787         try {
    788             sync.getWaitingThreads(c);
    789             shouldThrow();
    790         } catch (IllegalMonitorStateException success) {}
    791         assertHasWaitersUnlocked(sync, c, NO_THREADS);
    792     }
    793 
    794     /**
    795      * hasWaiters returns true when a thread is waiting, else false
    796      */
    797     public void testHasWaiters() {
    798         final Mutex sync = new Mutex();
    799         final ConditionObject c = sync.newCondition();
    800         final BooleanLatch acquired = new BooleanLatch();
    801         Thread t = newStartedThread(new CheckedRunnable() {
    802             public void realRun() throws InterruptedException {
    803                 sync.acquire();
    804                 assertHasWaitersLocked(sync, c, NO_THREADS);
    805                 assertFalse(sync.hasWaiters(c));
    806                 assertTrue(acquired.releaseShared(0));
    807                 c.await();
    808                 sync.release();
    809             }});
    810 
    811         acquired.acquireShared(0);
    812         sync.acquire();
    813         assertHasWaitersLocked(sync, c, t);
    814         assertHasExclusiveQueuedThreads(sync, NO_THREADS);
    815         assertTrue(sync.hasWaiters(c));
    816         c.signal();
    817         assertHasWaitersLocked(sync, c, NO_THREADS);
    818         assertHasExclusiveQueuedThreads(sync, t);
    819         assertFalse(sync.hasWaiters(c));
    820         sync.release();
    821 
    822         awaitTermination(t);
    823         assertHasWaitersUnlocked(sync, c, NO_THREADS);
    824     }
    825 
    826     /**
    827      * getWaitQueueLength returns number of waiting threads
    828      */
    829     public void testGetWaitQueueLength() {
    830         final Mutex sync = new Mutex();
    831         final ConditionObject c = sync.newCondition();
    832         final BooleanLatch acquired1 = new BooleanLatch();
    833         final BooleanLatch acquired2 = new BooleanLatch();
    834         final Thread t1 = newStartedThread(new CheckedRunnable() {
    835             public void realRun() throws InterruptedException {
    836                 sync.acquire();
    837                 assertHasWaitersLocked(sync, c, NO_THREADS);
    838                 assertEquals(0, sync.getWaitQueueLength(c));
    839                 assertTrue(acquired1.releaseShared(0));
    840                 c.await();
    841                 sync.release();
    842             }});
    843         acquired1.acquireShared(0);
    844         sync.acquire();
    845         assertHasWaitersLocked(sync, c, t1);
    846         assertEquals(1, sync.getWaitQueueLength(c));
    847         sync.release();
    848 
    849         final Thread t2 = newStartedThread(new CheckedRunnable() {
    850             public void realRun() throws InterruptedException {
    851                 sync.acquire();
    852                 assertHasWaitersLocked(sync, c, t1);
    853                 assertEquals(1, sync.getWaitQueueLength(c));
    854                 assertTrue(acquired2.releaseShared(0));
    855                 c.await();
    856                 sync.release();
    857             }});
    858         acquired2.acquireShared(0);
    859         sync.acquire();
    860         assertHasWaitersLocked(sync, c, t1, t2);
    861         assertHasExclusiveQueuedThreads(sync, NO_THREADS);
    862         assertEquals(2, sync.getWaitQueueLength(c));
    863         c.signalAll();
    864         assertHasWaitersLocked(sync, c, NO_THREADS);
    865         assertHasExclusiveQueuedThreads(sync, t1, t2);
    866         assertEquals(0, sync.getWaitQueueLength(c));
    867         sync.release();
    868 
    869         awaitTermination(t1);
    870         awaitTermination(t2);
    871         assertHasWaitersUnlocked(sync, c, NO_THREADS);
    872     }
    873 
    874     /**
    875      * getWaitingThreads returns only and all waiting threads
    876      */
    877     public void testGetWaitingThreads() {
    878         final Mutex sync = new Mutex();
    879         final ConditionObject c = sync.newCondition();
    880         final BooleanLatch acquired1 = new BooleanLatch();
    881         final BooleanLatch acquired2 = new BooleanLatch();
    882         final Thread t1 = new Thread(new CheckedRunnable() {
    883             public void realRun() throws InterruptedException {
    884                 sync.acquire();
    885                 assertHasWaitersLocked(sync, c, NO_THREADS);
    886                 assertTrue(sync.getWaitingThreads(c).isEmpty());
    887                 assertTrue(acquired1.releaseShared(0));
    888                 c.await();
    889                 sync.release();
    890             }});
    891 
    892         final Thread t2 = new Thread(new CheckedRunnable() {
    893             public void realRun() throws InterruptedException {
    894                 sync.acquire();
    895                 assertHasWaitersLocked(sync, c, t1);
    896                 assertTrue(sync.getWaitingThreads(c).contains(t1));
    897                 assertFalse(sync.getWaitingThreads(c).isEmpty());
    898                 assertEquals(1, sync.getWaitingThreads(c).size());
    899                 assertTrue(acquired2.releaseShared(0));
    900                 c.await();
    901                 sync.release();
    902             }});
    903 
    904         sync.acquire();
    905         assertHasWaitersLocked(sync, c, NO_THREADS);
    906         assertFalse(sync.getWaitingThreads(c).contains(t1));
    907         assertFalse(sync.getWaitingThreads(c).contains(t2));
    908         assertTrue(sync.getWaitingThreads(c).isEmpty());
    909         assertEquals(0, sync.getWaitingThreads(c).size());
    910         sync.release();
    911 
    912         t1.start();
    913         acquired1.acquireShared(0);
    914         sync.acquire();
    915         assertHasWaitersLocked(sync, c, t1);
    916         assertTrue(sync.getWaitingThreads(c).contains(t1));
    917         assertFalse(sync.getWaitingThreads(c).contains(t2));
    918         assertFalse(sync.getWaitingThreads(c).isEmpty());
    919         assertEquals(1, sync.getWaitingThreads(c).size());
    920         sync.release();
    921 
    922         t2.start();
    923         acquired2.acquireShared(0);
    924         sync.acquire();
    925         assertHasWaitersLocked(sync, c, t1, t2);
    926         assertHasExclusiveQueuedThreads(sync, NO_THREADS);
    927         assertTrue(sync.getWaitingThreads(c).contains(t1));
    928         assertTrue(sync.getWaitingThreads(c).contains(t2));
    929         assertFalse(sync.getWaitingThreads(c).isEmpty());
    930         assertEquals(2, sync.getWaitingThreads(c).size());
    931         c.signalAll();
    932         assertHasWaitersLocked(sync, c, NO_THREADS);
    933         assertHasExclusiveQueuedThreads(sync, t1, t2);
    934         assertFalse(sync.getWaitingThreads(c).contains(t1));
    935         assertFalse(sync.getWaitingThreads(c).contains(t2));
    936         assertTrue(sync.getWaitingThreads(c).isEmpty());
    937         assertEquals(0, sync.getWaitingThreads(c).size());
    938         sync.release();
    939 
    940         awaitTermination(t1);
    941         awaitTermination(t2);
    942         assertHasWaitersUnlocked(sync, c, NO_THREADS);
    943     }
    944 
    945     /**
    946      * awaitUninterruptibly is uninterruptible
    947      */
    948     public void testAwaitUninterruptibly() {
    949         final Mutex sync = new Mutex();
    950         final ConditionObject c = sync.newCondition();
    951         final BooleanLatch pleaseInterrupt = new BooleanLatch();
    952         Thread t = newStartedThread(new CheckedRunnable() {
    953             public void realRun() {
    954                 sync.acquire();
    955                 assertTrue(pleaseInterrupt.releaseShared(0));
    956                 c.awaitUninterruptibly();
    957                 assertTrue(Thread.interrupted());
    958                 assertHasWaitersLocked(sync, c, NO_THREADS);
    959                 sync.release();
    960             }});
    961 
    962         pleaseInterrupt.acquireShared(0);
    963         sync.acquire();
    964         assertHasWaitersLocked(sync, c, t);
    965         sync.release();
    966         t.interrupt();
    967         assertHasWaitersUnlocked(sync, c, t);
    968         assertThreadStaysAlive(t);
    969         sync.acquire();
    970         assertHasWaitersLocked(sync, c, t);
    971         assertHasExclusiveQueuedThreads(sync, NO_THREADS);
    972         c.signal();
    973         assertHasWaitersLocked(sync, c, NO_THREADS);
    974         assertHasExclusiveQueuedThreads(sync, t);
    975         sync.release();
    976         awaitTermination(t);
    977     }
    978 
    979     /**
    980      * await/awaitNanos/awaitUntil is interruptible
    981      */
    982     public void testInterruptible_await()      { testInterruptible(AwaitMethod.await); }
    983     public void testInterruptible_awaitTimed() { testInterruptible(AwaitMethod.awaitTimed); }
    984     public void testInterruptible_awaitNanos() { testInterruptible(AwaitMethod.awaitNanos); }
    985     public void testInterruptible_awaitUntil() { testInterruptible(AwaitMethod.awaitUntil); }
    986     public void testInterruptible(final AwaitMethod awaitMethod) {
    987         final Mutex sync = new Mutex();
    988         final ConditionObject c = sync.newCondition();
    989         final BooleanLatch pleaseInterrupt = new BooleanLatch();
    990         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
    991             public void realRun() throws InterruptedException {
    992                 sync.acquire();
    993                 assertTrue(pleaseInterrupt.releaseShared(0));
    994                 await(c, awaitMethod);
    995             }});
    996 
    997         pleaseInterrupt.acquireShared(0);
    998         t.interrupt();
    999         awaitTermination(t);
   1000     }
   1001 
   1002     /**
   1003      * signalAll wakes up all threads
   1004      */
   1005     public void testSignalAll_await()      { testSignalAll(AwaitMethod.await); }
   1006     public void testSignalAll_awaitTimed() { testSignalAll(AwaitMethod.awaitTimed); }
   1007     public void testSignalAll_awaitNanos() { testSignalAll(AwaitMethod.awaitNanos); }
   1008     public void testSignalAll_awaitUntil() { testSignalAll(AwaitMethod.awaitUntil); }
   1009     public void testSignalAll(final AwaitMethod awaitMethod) {
   1010         final Mutex sync = new Mutex();
   1011         final ConditionObject c = sync.newCondition();
   1012         final BooleanLatch acquired1 = new BooleanLatch();
   1013         final BooleanLatch acquired2 = new BooleanLatch();
   1014         Thread t1 = newStartedThread(new CheckedRunnable() {
   1015             public void realRun() throws InterruptedException {
   1016                 sync.acquire();
   1017                 acquired1.releaseShared(0);
   1018                 await(c, awaitMethod);
   1019                 sync.release();
   1020             }});
   1021 
   1022         Thread t2 = newStartedThread(new CheckedRunnable() {
   1023             public void realRun() throws InterruptedException {
   1024                 sync.acquire();
   1025                 acquired2.releaseShared(0);
   1026                 await(c, awaitMethod);
   1027                 sync.release();
   1028             }});
   1029 
   1030         acquired1.acquireShared(0);
   1031         acquired2.acquireShared(0);
   1032         sync.acquire();
   1033         assertHasWaitersLocked(sync, c, t1, t2);
   1034         assertHasExclusiveQueuedThreads(sync, NO_THREADS);
   1035         c.signalAll();
   1036         assertHasWaitersLocked(sync, c, NO_THREADS);
   1037         assertHasExclusiveQueuedThreads(sync, t1, t2);
   1038         sync.release();
   1039         awaitTermination(t1);
   1040         awaitTermination(t2);
   1041     }
   1042 
   1043     /**
   1044      * toString indicates current state
   1045      */
   1046     public void testToString() {
   1047         Mutex sync = new Mutex();
   1048         assertTrue(sync.toString().contains("State = " + Mutex.UNLOCKED));
   1049         sync.acquire();
   1050         assertTrue(sync.toString().contains("State = " + Mutex.LOCKED));
   1051     }
   1052 
   1053     /**
   1054      * A serialized AQS deserializes with current state, but no queued threads
   1055      */
   1056     public void testSerialization() {
   1057         Mutex sync = new Mutex();
   1058         assertFalse(serialClone(sync).isHeldExclusively());
   1059         sync.acquire();
   1060         Thread t = newStartedThread(new InterruptedSyncRunnable(sync));
   1061         waitForQueuedThread(sync, t);
   1062         assertTrue(sync.isHeldExclusively());
   1063 
   1064         Mutex clone = serialClone(sync);
   1065         assertTrue(clone.isHeldExclusively());
   1066         assertHasExclusiveQueuedThreads(sync, t);
   1067         assertHasExclusiveQueuedThreads(clone, NO_THREADS);
   1068         t.interrupt();
   1069         awaitTermination(t);
   1070         sync.release();
   1071         assertFalse(sync.isHeldExclusively());
   1072         assertTrue(clone.isHeldExclusively());
   1073         assertHasExclusiveQueuedThreads(sync, NO_THREADS);
   1074         assertHasExclusiveQueuedThreads(clone, NO_THREADS);
   1075     }
   1076 
   1077     /**
   1078      * tryReleaseShared setting state changes getState
   1079      */
   1080     public void testGetStateWithReleaseShared() {
   1081         final BooleanLatch l = new BooleanLatch();
   1082         assertFalse(l.isSignalled());
   1083         assertTrue(l.releaseShared(0));
   1084         assertTrue(l.isSignalled());
   1085     }
   1086 
   1087     /**
   1088      * releaseShared has no effect when already signalled
   1089      */
   1090     public void testReleaseShared() {
   1091         final BooleanLatch l = new BooleanLatch();
   1092         assertFalse(l.isSignalled());
   1093         assertTrue(l.releaseShared(0));
   1094         assertTrue(l.isSignalled());
   1095         assertTrue(l.releaseShared(0));
   1096         assertTrue(l.isSignalled());
   1097     }
   1098 
   1099     /**
   1100      * acquireSharedInterruptibly returns after release, but not before
   1101      */
   1102     public void testAcquireSharedInterruptibly() {
   1103         final BooleanLatch l = new BooleanLatch();
   1104 
   1105         Thread t = newStartedThread(new CheckedRunnable() {
   1106             public void realRun() throws InterruptedException {
   1107                 assertFalse(l.isSignalled());
   1108                 l.acquireSharedInterruptibly(0);
   1109                 assertTrue(l.isSignalled());
   1110                 l.acquireSharedInterruptibly(0);
   1111                 assertTrue(l.isSignalled());
   1112             }});
   1113 
   1114         waitForQueuedThread(l, t);
   1115         assertFalse(l.isSignalled());
   1116         assertThreadStaysAlive(t);
   1117         assertHasSharedQueuedThreads(l, t);
   1118         assertTrue(l.releaseShared(0));
   1119         assertTrue(l.isSignalled());
   1120         awaitTermination(t);
   1121     }
   1122 
   1123     /**
   1124      * tryAcquireSharedNanos returns after release, but not before
   1125      */
   1126     public void testTryAcquireSharedNanos() {
   1127         final BooleanLatch l = new BooleanLatch();
   1128 
   1129         Thread t = newStartedThread(new CheckedRunnable() {
   1130             public void realRun() throws InterruptedException {
   1131                 assertFalse(l.isSignalled());
   1132                 long nanos = MILLISECONDS.toNanos(2 * LONG_DELAY_MS);
   1133                 assertTrue(l.tryAcquireSharedNanos(0, nanos));
   1134                 assertTrue(l.isSignalled());
   1135                 assertTrue(l.tryAcquireSharedNanos(0, nanos));
   1136                 assertTrue(l.isSignalled());
   1137             }});
   1138 
   1139         waitForQueuedThread(l, t);
   1140         assertFalse(l.isSignalled());
   1141         assertThreadStaysAlive(t);
   1142         assertTrue(l.releaseShared(0));
   1143         assertTrue(l.isSignalled());
   1144         awaitTermination(t);
   1145     }
   1146 
   1147     /**
   1148      * acquireSharedInterruptibly is interruptible
   1149      */
   1150     public void testAcquireSharedInterruptibly_Interruptible() {
   1151         final BooleanLatch l = new BooleanLatch();
   1152         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
   1153             public void realRun() throws InterruptedException {
   1154                 assertFalse(l.isSignalled());
   1155                 l.acquireSharedInterruptibly(0);
   1156             }});
   1157 
   1158         waitForQueuedThread(l, t);
   1159         assertFalse(l.isSignalled());
   1160         t.interrupt();
   1161         awaitTermination(t);
   1162         assertFalse(l.isSignalled());
   1163     }
   1164 
   1165     /**
   1166      * tryAcquireSharedNanos is interruptible
   1167      */
   1168     public void testTryAcquireSharedNanos_Interruptible() {
   1169         final BooleanLatch l = new BooleanLatch();
   1170         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
   1171             public void realRun() throws InterruptedException {
   1172                 assertFalse(l.isSignalled());
   1173                 long nanos = MILLISECONDS.toNanos(2 * LONG_DELAY_MS);
   1174                 l.tryAcquireSharedNanos(0, nanos);
   1175             }});
   1176 
   1177         waitForQueuedThread(l, t);
   1178         assertFalse(l.isSignalled());
   1179         t.interrupt();
   1180         awaitTermination(t);
   1181         assertFalse(l.isSignalled());
   1182     }
   1183 
   1184     /**
   1185      * tryAcquireSharedNanos times out if not released before timeout
   1186      */
   1187     public void testTryAcquireSharedNanos_Timeout() {
   1188         final BooleanLatch l = new BooleanLatch();
   1189         final BooleanLatch observedQueued = new BooleanLatch();
   1190         final long timeoutMillis = timeoutMillis();
   1191         Thread t = newStartedThread(new CheckedRunnable() {
   1192             public void realRun() throws InterruptedException {
   1193                 assertFalse(l.isSignalled());
   1194                 for (long millis = timeoutMillis();
   1195                      !observedQueued.isSignalled();
   1196                      millis *= 2) {
   1197                     long nanos = MILLISECONDS.toNanos(millis);
   1198                     long startTime = System.nanoTime();
   1199                     assertFalse(l.tryAcquireSharedNanos(0, nanos));
   1200                     assertTrue(millisElapsedSince(startTime) >= millis);
   1201                 }
   1202                 assertFalse(l.isSignalled());
   1203             }});
   1204 
   1205         waitForQueuedThread(l, t);
   1206         observedQueued.releaseShared(0);
   1207         assertFalse(l.isSignalled());
   1208         awaitTermination(t);
   1209         assertFalse(l.isSignalled());
   1210     }
   1211 
   1212 }
   1213