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