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.concurrent.locks.Condition;
     13 import java.util.concurrent.locks.ReentrantLock;
     14 import java.util.concurrent.CountDownLatch;
     15 import java.util.concurrent.CyclicBarrier;
     16 import static java.util.concurrent.TimeUnit.MILLISECONDS;
     17 import java.util.*;
     18 
     19 public class ReentrantLockTest extends JSR166TestCase {
     20 
     21     /**
     22      * A runnable calling lockInterruptibly
     23      */
     24     class InterruptibleLockRunnable extends CheckedRunnable {
     25         final ReentrantLock lock;
     26         InterruptibleLockRunnable(ReentrantLock l) { lock = l; }
     27         public void realRun() throws InterruptedException {
     28             lock.lockInterruptibly();
     29         }
     30     }
     31 
     32     /**
     33      * A runnable calling lockInterruptibly that expects to be
     34      * interrupted
     35      */
     36     class InterruptedLockRunnable extends CheckedInterruptedRunnable {
     37         final ReentrantLock lock;
     38         InterruptedLockRunnable(ReentrantLock l) { lock = l; }
     39         public void realRun() throws InterruptedException {
     40             lock.lockInterruptibly();
     41         }
     42     }
     43 
     44     /**
     45      * Subclass to expose protected methods
     46      */
     47     static class PublicReentrantLock extends ReentrantLock {
     48         PublicReentrantLock() { super(); }
     49         PublicReentrantLock(boolean fair) { super(fair); }
     50         public Thread getOwner() {
     51             return super.getOwner();
     52         }
     53         public Collection<Thread> getQueuedThreads() {
     54             return super.getQueuedThreads();
     55         }
     56         public Collection<Thread> getWaitingThreads(Condition c) {
     57             return super.getWaitingThreads(c);
     58         }
     59     }
     60 
     61     /**
     62      * Releases write lock, checking that it had a hold count of 1.
     63      */
     64     void releaseLock(PublicReentrantLock lock) {
     65         assertLockedByMoi(lock);
     66         lock.unlock();
     67         assertFalse(lock.isHeldByCurrentThread());
     68         assertNotLocked(lock);
     69     }
     70 
     71     /**
     72      * Spin-waits until lock.hasQueuedThread(t) becomes true.
     73      */
     74     void waitForQueuedThread(PublicReentrantLock lock, Thread t) {
     75         long startTime = System.nanoTime();
     76         while (!lock.hasQueuedThread(t)) {
     77             if (millisElapsedSince(startTime) > LONG_DELAY_MS)
     78                 throw new AssertionFailedError("timed out");
     79             Thread.yield();
     80         }
     81         assertTrue(t.isAlive());
     82         assertNotSame(t, lock.getOwner());
     83     }
     84 
     85     /**
     86      * Checks that lock is not locked.
     87      */
     88     void assertNotLocked(PublicReentrantLock lock) {
     89         assertFalse(lock.isLocked());
     90         assertFalse(lock.isHeldByCurrentThread());
     91         assertNull(lock.getOwner());
     92         assertEquals(0, lock.getHoldCount());
     93     }
     94 
     95     /**
     96      * Checks that lock is locked by the given thread.
     97      */
     98     void assertLockedBy(PublicReentrantLock lock, Thread t) {
     99         assertTrue(lock.isLocked());
    100         assertSame(t, lock.getOwner());
    101         assertEquals(t == Thread.currentThread(),
    102                      lock.isHeldByCurrentThread());
    103         assertEquals(t == Thread.currentThread(),
    104                      lock.getHoldCount() > 0);
    105     }
    106 
    107     /**
    108      * Checks that lock is locked by the current thread.
    109      */
    110     void assertLockedByMoi(PublicReentrantLock lock) {
    111         assertLockedBy(lock, Thread.currentThread());
    112     }
    113 
    114     /**
    115      * Checks that condition c has no waiters.
    116      */
    117     void assertHasNoWaiters(PublicReentrantLock lock, Condition c) {
    118         assertHasWaiters(lock, c, new Thread[] {});
    119     }
    120 
    121     /**
    122      * Checks that condition c has exactly the given waiter threads.
    123      */
    124     void assertHasWaiters(PublicReentrantLock lock, Condition c,
    125                           Thread... threads) {
    126         lock.lock();
    127         assertEquals(threads.length > 0, lock.hasWaiters(c));
    128         assertEquals(threads.length, lock.getWaitQueueLength(c));
    129         assertEquals(threads.length == 0, lock.getWaitingThreads(c).isEmpty());
    130         assertEquals(threads.length, lock.getWaitingThreads(c).size());
    131         assertEquals(new HashSet<Thread>(lock.getWaitingThreads(c)),
    132                      new HashSet<Thread>(Arrays.asList(threads)));
    133         lock.unlock();
    134     }
    135 
    136     enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil };
    137 
    138     /**
    139      * Awaits condition using the specified AwaitMethod.
    140      */
    141     void await(Condition c, AwaitMethod awaitMethod)
    142             throws InterruptedException {
    143         long timeoutMillis = 2 * LONG_DELAY_MS;
    144         switch (awaitMethod) {
    145         case await:
    146             c.await();
    147             break;
    148         case awaitTimed:
    149             assertTrue(c.await(timeoutMillis, MILLISECONDS));
    150             break;
    151         case awaitNanos:
    152             long nanosTimeout = MILLISECONDS.toNanos(timeoutMillis);
    153             long nanosRemaining = c.awaitNanos(nanosTimeout);
    154             assertTrue(nanosRemaining > 0);
    155             break;
    156         case awaitUntil:
    157             assertTrue(c.awaitUntil(delayedDate(timeoutMillis)));
    158             break;
    159         }
    160     }
    161 
    162     /**
    163      * Constructor sets given fairness, and is in unlocked state
    164      */
    165     public void testConstructor() {
    166         PublicReentrantLock lock;
    167 
    168         lock = new PublicReentrantLock();
    169         assertFalse(lock.isFair());
    170         assertNotLocked(lock);
    171 
    172         lock = new PublicReentrantLock(true);
    173         assertTrue(lock.isFair());
    174         assertNotLocked(lock);
    175 
    176         lock = new PublicReentrantLock(false);
    177         assertFalse(lock.isFair());
    178         assertNotLocked(lock);
    179     }
    180 
    181     /**
    182      * locking an unlocked lock succeeds
    183      */
    184     public void testLock()      { testLock(false); }
    185     public void testLock_fair() { testLock(true); }
    186     public void testLock(boolean fair) {
    187         PublicReentrantLock lock = new PublicReentrantLock(fair);
    188         lock.lock();
    189         assertLockedByMoi(lock);
    190         releaseLock(lock);
    191     }
    192 
    193     /**
    194      * Unlocking an unlocked lock throws IllegalMonitorStateException
    195      */
    196     public void testUnlock_IMSE()      { testUnlock_IMSE(false); }
    197     public void testUnlock_IMSE_fair() { testUnlock_IMSE(true); }
    198     public void testUnlock_IMSE(boolean fair) {
    199         ReentrantLock lock = new ReentrantLock(fair);
    200         try {
    201             lock.unlock();
    202             shouldThrow();
    203         } catch (IllegalMonitorStateException success) {}
    204     }
    205 
    206     /**
    207      * tryLock on an unlocked lock succeeds
    208      */
    209     public void testTryLock()      { testTryLock(false); }
    210     public void testTryLock_fair() { testTryLock(true); }
    211     public void testTryLock(boolean fair) {
    212         PublicReentrantLock lock = new PublicReentrantLock(fair);
    213         assertTrue(lock.tryLock());
    214         assertLockedByMoi(lock);
    215         assertTrue(lock.tryLock());
    216         assertLockedByMoi(lock);
    217         lock.unlock();
    218         releaseLock(lock);
    219     }
    220 
    221     /**
    222      * hasQueuedThreads reports whether there are waiting threads
    223      */
    224     public void testHasQueuedThreads()      { testHasQueuedThreads(false); }
    225     public void testHasQueuedThreads_fair() { testHasQueuedThreads(true); }
    226     public void testHasQueuedThreads(boolean fair) {
    227         final PublicReentrantLock lock = new PublicReentrantLock(fair);
    228         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
    229         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
    230         assertFalse(lock.hasQueuedThreads());
    231         lock.lock();
    232         assertFalse(lock.hasQueuedThreads());
    233         t1.start();
    234         waitForQueuedThread(lock, t1);
    235         assertTrue(lock.hasQueuedThreads());
    236         t2.start();
    237         waitForQueuedThread(lock, t2);
    238         assertTrue(lock.hasQueuedThreads());
    239         t1.interrupt();
    240         awaitTermination(t1);
    241         assertTrue(lock.hasQueuedThreads());
    242         lock.unlock();
    243         awaitTermination(t2);
    244         assertFalse(lock.hasQueuedThreads());
    245     }
    246 
    247     /**
    248      * getQueueLength reports number of waiting threads
    249      */
    250     public void testGetQueueLength()      { testGetQueueLength(false); }
    251     public void testGetQueueLength_fair() { testGetQueueLength(true); }
    252     public void testGetQueueLength(boolean fair) {
    253         final PublicReentrantLock lock = new PublicReentrantLock(fair);
    254         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
    255         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
    256         assertEquals(0, lock.getQueueLength());
    257         lock.lock();
    258         t1.start();
    259         waitForQueuedThread(lock, t1);
    260         assertEquals(1, lock.getQueueLength());
    261         t2.start();
    262         waitForQueuedThread(lock, t2);
    263         assertEquals(2, lock.getQueueLength());
    264         t1.interrupt();
    265         awaitTermination(t1);
    266         assertEquals(1, lock.getQueueLength());
    267         lock.unlock();
    268         awaitTermination(t2);
    269         assertEquals(0, lock.getQueueLength());
    270     }
    271 
    272     /**
    273      * hasQueuedThread(null) throws NPE
    274      */
    275     public void testHasQueuedThreadNPE()      { testHasQueuedThreadNPE(false); }
    276     public void testHasQueuedThreadNPE_fair() { testHasQueuedThreadNPE(true); }
    277     public void testHasQueuedThreadNPE(boolean fair) {
    278         final ReentrantLock lock = new ReentrantLock(fair);
    279         try {
    280             lock.hasQueuedThread(null);
    281             shouldThrow();
    282         } catch (NullPointerException success) {}
    283     }
    284 
    285     /**
    286      * hasQueuedThread reports whether a thread is queued
    287      */
    288     public void testHasQueuedThread()      { testHasQueuedThread(false); }
    289     public void testHasQueuedThread_fair() { testHasQueuedThread(true); }
    290     public void testHasQueuedThread(boolean fair) {
    291         final PublicReentrantLock lock = new PublicReentrantLock(fair);
    292         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
    293         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
    294         assertFalse(lock.hasQueuedThread(t1));
    295         assertFalse(lock.hasQueuedThread(t2));
    296         lock.lock();
    297         t1.start();
    298         waitForQueuedThread(lock, t1);
    299         assertTrue(lock.hasQueuedThread(t1));
    300         assertFalse(lock.hasQueuedThread(t2));
    301         t2.start();
    302         waitForQueuedThread(lock, t2);
    303         assertTrue(lock.hasQueuedThread(t1));
    304         assertTrue(lock.hasQueuedThread(t2));
    305         t1.interrupt();
    306         awaitTermination(t1);
    307         assertFalse(lock.hasQueuedThread(t1));
    308         assertTrue(lock.hasQueuedThread(t2));
    309         lock.unlock();
    310         awaitTermination(t2);
    311         assertFalse(lock.hasQueuedThread(t1));
    312         assertFalse(lock.hasQueuedThread(t2));
    313     }
    314 
    315     /**
    316      * getQueuedThreads includes waiting threads
    317      */
    318     public void testGetQueuedThreads()      { testGetQueuedThreads(false); }
    319     public void testGetQueuedThreads_fair() { testGetQueuedThreads(true); }
    320     public void testGetQueuedThreads(boolean fair) {
    321         final PublicReentrantLock lock = new PublicReentrantLock(fair);
    322         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
    323         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
    324         assertTrue(lock.getQueuedThreads().isEmpty());
    325         lock.lock();
    326         assertTrue(lock.getQueuedThreads().isEmpty());
    327         t1.start();
    328         waitForQueuedThread(lock, t1);
    329         assertEquals(1, lock.getQueuedThreads().size());
    330         assertTrue(lock.getQueuedThreads().contains(t1));
    331         t2.start();
    332         waitForQueuedThread(lock, t2);
    333         assertEquals(2, lock.getQueuedThreads().size());
    334         assertTrue(lock.getQueuedThreads().contains(t1));
    335         assertTrue(lock.getQueuedThreads().contains(t2));
    336         t1.interrupt();
    337         awaitTermination(t1);
    338         assertFalse(lock.getQueuedThreads().contains(t1));
    339         assertTrue(lock.getQueuedThreads().contains(t2));
    340         assertEquals(1, lock.getQueuedThreads().size());
    341         lock.unlock();
    342         awaitTermination(t2);
    343         assertTrue(lock.getQueuedThreads().isEmpty());
    344     }
    345 
    346     /**
    347      * timed tryLock is interruptible
    348      */
    349     public void testTryLock_Interruptible()      { testTryLock_Interruptible(false); }
    350     public void testTryLock_Interruptible_fair() { testTryLock_Interruptible(true); }
    351     public void testTryLock_Interruptible(boolean fair) {
    352         final PublicReentrantLock lock = new PublicReentrantLock(fair);
    353         lock.lock();
    354         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
    355             public void realRun() throws InterruptedException {
    356                 lock.tryLock(2 * LONG_DELAY_MS, MILLISECONDS);
    357             }});
    358 
    359         waitForQueuedThread(lock, t);
    360         t.interrupt();
    361         awaitTermination(t);
    362         releaseLock(lock);
    363     }
    364 
    365     /**
    366      * tryLock on a locked lock fails
    367      */
    368     public void testTryLockWhenLocked()      { testTryLockWhenLocked(false); }
    369     public void testTryLockWhenLocked_fair() { testTryLockWhenLocked(true); }
    370     public void testTryLockWhenLocked(boolean fair) {
    371         final PublicReentrantLock lock = new PublicReentrantLock(fair);
    372         lock.lock();
    373         Thread t = newStartedThread(new CheckedRunnable() {
    374             public void realRun() {
    375                 assertFalse(lock.tryLock());
    376             }});
    377 
    378         awaitTermination(t);
    379         releaseLock(lock);
    380     }
    381 
    382     /**
    383      * Timed tryLock on a locked lock times out
    384      */
    385     public void testTryLock_Timeout()      { testTryLock_Timeout(false); }
    386     public void testTryLock_Timeout_fair() { testTryLock_Timeout(true); }
    387     public void testTryLock_Timeout(boolean fair) {
    388         final PublicReentrantLock lock = new PublicReentrantLock(fair);
    389         lock.lock();
    390         Thread t = newStartedThread(new CheckedRunnable() {
    391             public void realRun() throws InterruptedException {
    392                 long startTime = System.nanoTime();
    393                 long timeoutMillis = 10;
    394                 assertFalse(lock.tryLock(timeoutMillis, MILLISECONDS));
    395                 assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
    396             }});
    397 
    398         awaitTermination(t);
    399         releaseLock(lock);
    400     }
    401 
    402     /**
    403      * getHoldCount returns number of recursive holds
    404      */
    405     public void testGetHoldCount()      { testGetHoldCount(false); }
    406     public void testGetHoldCount_fair() { testGetHoldCount(true); }
    407     public void testGetHoldCount(boolean fair) {
    408         ReentrantLock lock = new ReentrantLock(fair);
    409         for (int i = 1; i <= SIZE; i++) {
    410             lock.lock();
    411             assertEquals(i, lock.getHoldCount());
    412         }
    413         for (int i = SIZE; i > 0; i--) {
    414             lock.unlock();
    415             assertEquals(i-1, lock.getHoldCount());
    416         }
    417     }
    418 
    419     /**
    420      * isLocked is true when locked and false when not
    421      */
    422     public void testIsLocked()      { testIsLocked(false); }
    423     public void testIsLocked_fair() { testIsLocked(true); }
    424     public void testIsLocked(boolean fair) {
    425         try {
    426             final ReentrantLock lock = new ReentrantLock(fair);
    427             assertFalse(lock.isLocked());
    428             lock.lock();
    429             assertTrue(lock.isLocked());
    430             lock.lock();
    431             assertTrue(lock.isLocked());
    432             lock.unlock();
    433             assertTrue(lock.isLocked());
    434             lock.unlock();
    435             assertFalse(lock.isLocked());
    436             final CyclicBarrier barrier = new CyclicBarrier(2);
    437             Thread t = newStartedThread(new CheckedRunnable() {
    438                     public void realRun() throws Exception {
    439                         lock.lock();
    440                         assertTrue(lock.isLocked());
    441                         barrier.await();
    442                         barrier.await();
    443                         lock.unlock();
    444                     }});
    445 
    446             barrier.await();
    447             assertTrue(lock.isLocked());
    448             barrier.await();
    449             awaitTermination(t);
    450             assertFalse(lock.isLocked());
    451         } catch (Exception e) {
    452             threadUnexpectedException(e);
    453         }
    454     }
    455 
    456     /**
    457      * lockInterruptibly succeeds when unlocked, else is interruptible
    458      */
    459     public void testLockInterruptibly()      { testLockInterruptibly(false); }
    460     public void testLockInterruptibly_fair() { testLockInterruptibly(true); }
    461     public void testLockInterruptibly(boolean fair) {
    462         final PublicReentrantLock lock = new PublicReentrantLock(fair);
    463         try {
    464             lock.lockInterruptibly();
    465         } catch (InterruptedException ie) {
    466             threadUnexpectedException(ie);
    467         }
    468         assertLockedByMoi(lock);
    469         Thread t = newStartedThread(new InterruptedLockRunnable(lock));
    470         waitForQueuedThread(lock, t);
    471         t.interrupt();
    472         assertTrue(lock.isLocked());
    473         assertTrue(lock.isHeldByCurrentThread());
    474         awaitTermination(t);
    475         releaseLock(lock);
    476     }
    477 
    478     /**
    479      * Calling await without holding lock throws IllegalMonitorStateException
    480      */
    481     public void testAwait_IMSE()      { testAwait_IMSE(false); }
    482     public void testAwait_IMSE_fair() { testAwait_IMSE(true); }
    483     public void testAwait_IMSE(boolean fair) {
    484         final ReentrantLock lock = new ReentrantLock(fair);
    485         final Condition c = lock.newCondition();
    486         for (AwaitMethod awaitMethod : AwaitMethod.values()) {
    487             long startTime = System.nanoTime();
    488             try {
    489                 await(c, awaitMethod);
    490                 shouldThrow();
    491             } catch (IllegalMonitorStateException success) {
    492             } catch (InterruptedException e) { threadUnexpectedException(e); }
    493             assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
    494         }
    495     }
    496 
    497     /**
    498      * Calling signal without holding lock throws IllegalMonitorStateException
    499      */
    500     public void testSignal_IMSE()      { testSignal_IMSE(false); }
    501     public void testSignal_IMSE_fair() { testSignal_IMSE(true); }
    502     public void testSignal_IMSE(boolean fair) {
    503         final ReentrantLock lock = new ReentrantLock(fair);
    504         final Condition c = lock.newCondition();
    505         try {
    506             c.signal();
    507             shouldThrow();
    508         } catch (IllegalMonitorStateException success) {}
    509     }
    510 
    511     /**
    512      * awaitNanos without a signal times out
    513      */
    514     public void testAwaitNanos_Timeout()      { testAwaitNanos_Timeout(false); }
    515     public void testAwaitNanos_Timeout_fair() { testAwaitNanos_Timeout(true); }
    516     public void testAwaitNanos_Timeout(boolean fair) {
    517         try {
    518             final ReentrantLock lock = new ReentrantLock(fair);
    519             final Condition c = lock.newCondition();
    520             lock.lock();
    521             long startTime = System.nanoTime();
    522             long timeoutMillis = 10;
    523             long timeoutNanos = MILLISECONDS.toNanos(timeoutMillis);
    524             long nanosRemaining = c.awaitNanos(timeoutNanos);
    525             assertTrue(nanosRemaining <= 0);
    526             assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
    527             lock.unlock();
    528         } catch (InterruptedException e) {
    529             threadUnexpectedException(e);
    530         }
    531     }
    532 
    533     /**
    534      * timed await without a signal times out
    535      */
    536     public void testAwait_Timeout()      { testAwait_Timeout(false); }
    537     public void testAwait_Timeout_fair() { testAwait_Timeout(true); }
    538     public void testAwait_Timeout(boolean fair) {
    539         try {
    540             final ReentrantLock lock = new ReentrantLock(fair);
    541             final Condition c = lock.newCondition();
    542             lock.lock();
    543             long startTime = System.nanoTime();
    544             long timeoutMillis = 10;
    545             assertFalse(c.await(timeoutMillis, MILLISECONDS));
    546             assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
    547             lock.unlock();
    548         } catch (InterruptedException e) {
    549             threadUnexpectedException(e);
    550         }
    551     }
    552 
    553     /**
    554      * awaitUntil without a signal times out
    555      */
    556     public void testAwaitUntil_Timeout()      { testAwaitUntil_Timeout(false); }
    557     public void testAwaitUntil_Timeout_fair() { testAwaitUntil_Timeout(true); }
    558     public void testAwaitUntil_Timeout(boolean fair) {
    559         try {
    560             final ReentrantLock lock = new ReentrantLock(fair);
    561             final Condition c = lock.newCondition();
    562             lock.lock();
    563             long startTime = System.nanoTime();
    564             long timeoutMillis = 10;
    565             java.util.Date d = new java.util.Date();
    566             assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + timeoutMillis)));
    567             assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
    568             lock.unlock();
    569         } catch (InterruptedException e) {
    570             threadUnexpectedException(e);
    571         }
    572     }
    573 
    574     /**
    575      * await returns when signalled
    576      */
    577     public void testAwait()      { testAwait(false); }
    578     public void testAwait_fair() { testAwait(true); }
    579     public void testAwait(boolean fair) {
    580         final PublicReentrantLock lock = new PublicReentrantLock(fair);
    581         final Condition c = lock.newCondition();
    582         final CountDownLatch locked = new CountDownLatch(1);
    583         Thread t = newStartedThread(new CheckedRunnable() {
    584             public void realRun() throws InterruptedException {
    585                 lock.lock();
    586                 locked.countDown();
    587                 c.await();
    588                 lock.unlock();
    589             }});
    590 
    591         await(locked);
    592         lock.lock();
    593         assertHasWaiters(lock, c, t);
    594         c.signal();
    595         assertHasNoWaiters(lock, c);
    596         assertTrue(t.isAlive());
    597         lock.unlock();
    598         awaitTermination(t);
    599     }
    600 
    601     /**
    602      * hasWaiters throws NPE if null
    603      */
    604     public void testHasWaitersNPE()      { testHasWaitersNPE(false); }
    605     public void testHasWaitersNPE_fair() { testHasWaitersNPE(true); }
    606     public void testHasWaitersNPE(boolean fair) {
    607         final ReentrantLock lock = new ReentrantLock(fair);
    608         try {
    609             lock.hasWaiters(null);
    610             shouldThrow();
    611         } catch (NullPointerException success) {}
    612     }
    613 
    614     /**
    615      * getWaitQueueLength throws NPE if null
    616      */
    617     public void testGetWaitQueueLengthNPE()      { testGetWaitQueueLengthNPE(false); }
    618     public void testGetWaitQueueLengthNPE_fair() { testGetWaitQueueLengthNPE(true); }
    619     public void testGetWaitQueueLengthNPE(boolean fair) {
    620         final ReentrantLock lock = new ReentrantLock(fair);
    621         try {
    622             lock.getWaitQueueLength(null);
    623             shouldThrow();
    624         } catch (NullPointerException success) {}
    625     }
    626 
    627     /**
    628      * getWaitingThreads throws NPE if null
    629      */
    630     public void testGetWaitingThreadsNPE()      { testGetWaitingThreadsNPE(false); }
    631     public void testGetWaitingThreadsNPE_fair() { testGetWaitingThreadsNPE(true); }
    632     public void testGetWaitingThreadsNPE(boolean fair) {
    633         final PublicReentrantLock lock = new PublicReentrantLock(fair);
    634         try {
    635             lock.getWaitingThreads(null);
    636             shouldThrow();
    637         } catch (NullPointerException success) {}
    638     }
    639 
    640     /**
    641      * hasWaiters throws IllegalArgumentException if not owned
    642      */
    643     public void testHasWaitersIAE()      { testHasWaitersIAE(false); }
    644     public void testHasWaitersIAE_fair() { testHasWaitersIAE(true); }
    645     public void testHasWaitersIAE(boolean fair) {
    646         final ReentrantLock lock = new ReentrantLock(fair);
    647         final Condition c = lock.newCondition();
    648         final ReentrantLock lock2 = new ReentrantLock(fair);
    649         try {
    650             lock2.hasWaiters(c);
    651             shouldThrow();
    652         } catch (IllegalArgumentException success) {}
    653     }
    654 
    655     /**
    656      * hasWaiters throws IllegalMonitorStateException if not locked
    657      */
    658     public void testHasWaitersIMSE()      { testHasWaitersIMSE(false); }
    659     public void testHasWaitersIMSE_fair() { testHasWaitersIMSE(true); }
    660     public void testHasWaitersIMSE(boolean fair) {
    661         final ReentrantLock lock = new ReentrantLock(fair);
    662         final Condition c = lock.newCondition();
    663         try {
    664             lock.hasWaiters(c);
    665             shouldThrow();
    666         } catch (IllegalMonitorStateException success) {}
    667     }
    668 
    669     /**
    670      * getWaitQueueLength throws IllegalArgumentException if not owned
    671      */
    672     public void testGetWaitQueueLengthIAE()      { testGetWaitQueueLengthIAE(false); }
    673     public void testGetWaitQueueLengthIAE_fair() { testGetWaitQueueLengthIAE(true); }
    674     public void testGetWaitQueueLengthIAE(boolean fair) {
    675         final ReentrantLock lock = new ReentrantLock(fair);
    676         final Condition c = lock.newCondition();
    677         final ReentrantLock lock2 = new ReentrantLock(fair);
    678         try {
    679             lock2.getWaitQueueLength(c);
    680             shouldThrow();
    681         } catch (IllegalArgumentException success) {}
    682     }
    683 
    684     /**
    685      * getWaitQueueLength throws IllegalMonitorStateException if not locked
    686      */
    687     public void testGetWaitQueueLengthIMSE()      { testGetWaitQueueLengthIMSE(false); }
    688     public void testGetWaitQueueLengthIMSE_fair() { testGetWaitQueueLengthIMSE(true); }
    689     public void testGetWaitQueueLengthIMSE(boolean fair) {
    690         final ReentrantLock lock = new ReentrantLock(fair);
    691         final Condition c = lock.newCondition();
    692         try {
    693             lock.getWaitQueueLength(c);
    694             shouldThrow();
    695         } catch (IllegalMonitorStateException success) {}
    696     }
    697 
    698     /**
    699      * getWaitingThreads throws IllegalArgumentException if not owned
    700      */
    701     public void testGetWaitingThreadsIAE()      { testGetWaitingThreadsIAE(false); }
    702     public void testGetWaitingThreadsIAE_fair() { testGetWaitingThreadsIAE(true); }
    703     public void testGetWaitingThreadsIAE(boolean fair) {
    704         final PublicReentrantLock lock = new PublicReentrantLock(fair);
    705         final Condition c = lock.newCondition();
    706         final PublicReentrantLock lock2 = new PublicReentrantLock(fair);
    707         try {
    708             lock2.getWaitingThreads(c);
    709             shouldThrow();
    710         } catch (IllegalArgumentException success) {}
    711     }
    712 
    713     /**
    714      * getWaitingThreads throws IllegalMonitorStateException if not locked
    715      */
    716     public void testGetWaitingThreadsIMSE()      { testGetWaitingThreadsIMSE(false); }
    717     public void testGetWaitingThreadsIMSE_fair() { testGetWaitingThreadsIMSE(true); }
    718     public void testGetWaitingThreadsIMSE(boolean fair) {
    719         final PublicReentrantLock lock = new PublicReentrantLock(fair);
    720         final Condition c = lock.newCondition();
    721         try {
    722             lock.getWaitingThreads(c);
    723             shouldThrow();
    724         } catch (IllegalMonitorStateException success) {}
    725     }
    726 
    727     /**
    728      * hasWaiters returns true when a thread is waiting, else false
    729      */
    730     public void testHasWaiters()      { testHasWaiters(false); }
    731     public void testHasWaiters_fair() { testHasWaiters(true); }
    732     public void testHasWaiters(boolean fair) {
    733         final PublicReentrantLock lock = new PublicReentrantLock(fair);
    734         final Condition c = lock.newCondition();
    735         final CountDownLatch pleaseSignal = new CountDownLatch(1);
    736         Thread t = newStartedThread(new CheckedRunnable() {
    737             public void realRun() throws InterruptedException {
    738                 lock.lock();
    739                 assertHasNoWaiters(lock, c);
    740                 assertFalse(lock.hasWaiters(c));
    741                 pleaseSignal.countDown();
    742                 c.await();
    743                 assertHasNoWaiters(lock, c);
    744                 assertFalse(lock.hasWaiters(c));
    745                 lock.unlock();
    746             }});
    747 
    748         await(pleaseSignal);
    749         lock.lock();
    750         assertHasWaiters(lock, c, t);
    751         assertTrue(lock.hasWaiters(c));
    752         c.signal();
    753         assertHasNoWaiters(lock, c);
    754         assertFalse(lock.hasWaiters(c));
    755         lock.unlock();
    756         awaitTermination(t);
    757         assertHasNoWaiters(lock, c);
    758     }
    759 
    760     /**
    761      * getWaitQueueLength returns number of waiting threads
    762      */
    763     public void testGetWaitQueueLength()      { testGetWaitQueueLength(false); }
    764     public void testGetWaitQueueLength_fair() { testGetWaitQueueLength(true); }
    765     public void testGetWaitQueueLength(boolean fair) {
    766         final PublicReentrantLock lock = new PublicReentrantLock(fair);
    767         final Condition c = lock.newCondition();
    768         final CountDownLatch locked1 = new CountDownLatch(1);
    769         final CountDownLatch locked2 = new CountDownLatch(1);
    770         Thread t1 = new Thread(new CheckedRunnable() {
    771             public void realRun() throws InterruptedException {
    772                 lock.lock();
    773                 assertFalse(lock.hasWaiters(c));
    774                 assertEquals(0, lock.getWaitQueueLength(c));
    775                 locked1.countDown();
    776                 c.await();
    777                 lock.unlock();
    778             }});
    779 
    780         Thread t2 = new Thread(new CheckedRunnable() {
    781             public void realRun() throws InterruptedException {
    782                 lock.lock();
    783                 assertTrue(lock.hasWaiters(c));
    784                 assertEquals(1, lock.getWaitQueueLength(c));
    785                 locked2.countDown();
    786                 c.await();
    787                 lock.unlock();
    788             }});
    789 
    790         lock.lock();
    791         assertEquals(0, lock.getWaitQueueLength(c));
    792         lock.unlock();
    793 
    794         t1.start();
    795         await(locked1);
    796 
    797         lock.lock();
    798         assertHasWaiters(lock, c, t1);
    799         assertEquals(1, lock.getWaitQueueLength(c));
    800         lock.unlock();
    801 
    802         t2.start();
    803         await(locked2);
    804 
    805         lock.lock();
    806         assertHasWaiters(lock, c, t1, t2);
    807         assertEquals(2, lock.getWaitQueueLength(c));
    808         c.signalAll();
    809         assertHasNoWaiters(lock, c);
    810         lock.unlock();
    811 
    812         awaitTermination(t1);
    813         awaitTermination(t2);
    814 
    815         assertHasNoWaiters(lock, c);
    816     }
    817 
    818     /**
    819      * getWaitingThreads returns only and all waiting threads
    820      */
    821     public void testGetWaitingThreads()      { testGetWaitingThreads(false); }
    822     public void testGetWaitingThreads_fair() { testGetWaitingThreads(true); }
    823     public void testGetWaitingThreads(boolean fair) {
    824         final PublicReentrantLock lock = new PublicReentrantLock(fair);
    825         final Condition c = lock.newCondition();
    826         final CountDownLatch locked1 = new CountDownLatch(1);
    827         final CountDownLatch locked2 = new CountDownLatch(1);
    828         Thread t1 = new Thread(new CheckedRunnable() {
    829             public void realRun() throws InterruptedException {
    830                 lock.lock();
    831                 assertTrue(lock.getWaitingThreads(c).isEmpty());
    832                 locked1.countDown();
    833                 c.await();
    834                 lock.unlock();
    835             }});
    836 
    837         Thread t2 = new Thread(new CheckedRunnable() {
    838             public void realRun() throws InterruptedException {
    839                 lock.lock();
    840                 assertFalse(lock.getWaitingThreads(c).isEmpty());
    841                 locked2.countDown();
    842                 c.await();
    843                 lock.unlock();
    844             }});
    845 
    846         lock.lock();
    847         assertTrue(lock.getWaitingThreads(c).isEmpty());
    848         lock.unlock();
    849 
    850         t1.start();
    851         await(locked1);
    852 
    853         lock.lock();
    854         assertHasWaiters(lock, c, t1);
    855         assertTrue(lock.getWaitingThreads(c).contains(t1));
    856         assertFalse(lock.getWaitingThreads(c).contains(t2));
    857         assertEquals(1, lock.getWaitingThreads(c).size());
    858         lock.unlock();
    859 
    860         t2.start();
    861         await(locked2);
    862 
    863         lock.lock();
    864         assertHasWaiters(lock, c, t1, t2);
    865         assertTrue(lock.getWaitingThreads(c).contains(t1));
    866         assertTrue(lock.getWaitingThreads(c).contains(t2));
    867         assertEquals(2, lock.getWaitingThreads(c).size());
    868         c.signalAll();
    869         assertHasNoWaiters(lock, c);
    870         lock.unlock();
    871 
    872         awaitTermination(t1);
    873         awaitTermination(t2);
    874 
    875         assertHasNoWaiters(lock, c);
    876     }
    877 
    878     /**
    879      * awaitUninterruptibly is uninterruptible
    880      */
    881     public void testAwaitUninterruptibly()      { testAwaitUninterruptibly(false); }
    882     public void testAwaitUninterruptibly_fair() { testAwaitUninterruptibly(true); }
    883     public void testAwaitUninterruptibly(boolean fair) {
    884         final ReentrantLock lock = new ReentrantLock(fair);
    885         final Condition c = lock.newCondition();
    886         final CountDownLatch pleaseInterrupt = new CountDownLatch(2);
    887 
    888         Thread t1 = newStartedThread(new CheckedRunnable() {
    889             public void realRun() {
    890                 // Interrupt before awaitUninterruptibly
    891                 lock.lock();
    892                 pleaseInterrupt.countDown();
    893                 Thread.currentThread().interrupt();
    894                 c.awaitUninterruptibly();
    895                 assertTrue(Thread.interrupted());
    896                 lock.unlock();
    897             }});
    898 
    899         Thread t2 = newStartedThread(new CheckedRunnable() {
    900             public void realRun() {
    901                 // Interrupt during awaitUninterruptibly
    902                 lock.lock();
    903                 pleaseInterrupt.countDown();
    904                 c.awaitUninterruptibly();
    905                 assertTrue(Thread.interrupted());
    906                 lock.unlock();
    907             }});
    908 
    909         await(pleaseInterrupt);
    910         lock.lock();
    911         lock.unlock();
    912         t2.interrupt();
    913 
    914         assertThreadStaysAlive(t1);
    915         assertTrue(t2.isAlive());
    916 
    917         lock.lock();
    918         c.signalAll();
    919         lock.unlock();
    920 
    921         awaitTermination(t1);
    922         awaitTermination(t2);
    923     }
    924 
    925     /**
    926      * await/awaitNanos/awaitUntil is interruptible
    927      */
    928     public void testInterruptible_await()           { testInterruptible(false, AwaitMethod.await); }
    929     public void testInterruptible_await_fair()      { testInterruptible(true,  AwaitMethod.await); }
    930     public void testInterruptible_awaitTimed()      { testInterruptible(false, AwaitMethod.awaitTimed); }
    931     public void testInterruptible_awaitTimed_fair() { testInterruptible(true,  AwaitMethod.awaitTimed); }
    932     public void testInterruptible_awaitNanos()      { testInterruptible(false, AwaitMethod.awaitNanos); }
    933     public void testInterruptible_awaitNanos_fair() { testInterruptible(true,  AwaitMethod.awaitNanos); }
    934     public void testInterruptible_awaitUntil()      { testInterruptible(false, AwaitMethod.awaitUntil); }
    935     public void testInterruptible_awaitUntil_fair() { testInterruptible(true,  AwaitMethod.awaitUntil); }
    936     public void testInterruptible(boolean fair, final AwaitMethod awaitMethod) {
    937         final PublicReentrantLock lock =
    938             new PublicReentrantLock(fair);
    939         final Condition c = lock.newCondition();
    940         final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
    941         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
    942             public void realRun() throws InterruptedException {
    943                 lock.lock();
    944                 assertLockedByMoi(lock);
    945                 assertHasNoWaiters(lock, c);
    946                 pleaseInterrupt.countDown();
    947                 try {
    948                     await(c, awaitMethod);
    949                 } finally {
    950                     assertLockedByMoi(lock);
    951                     assertHasNoWaiters(lock, c);
    952                     lock.unlock();
    953                     assertFalse(Thread.interrupted());
    954                 }
    955             }});
    956 
    957         await(pleaseInterrupt);
    958         assertHasWaiters(lock, c, t);
    959         t.interrupt();
    960         awaitTermination(t);
    961         assertNotLocked(lock);
    962     }
    963 
    964     /**
    965      * signalAll wakes up all threads
    966      */
    967     public void testSignalAll_await()           { testSignalAll(false, AwaitMethod.await); }
    968     public void testSignalAll_await_fair()      { testSignalAll(true,  AwaitMethod.await); }
    969     public void testSignalAll_awaitTimed()      { testSignalAll(false, AwaitMethod.awaitTimed); }
    970     public void testSignalAll_awaitTimed_fair() { testSignalAll(true,  AwaitMethod.awaitTimed); }
    971     public void testSignalAll_awaitNanos()      { testSignalAll(false, AwaitMethod.awaitNanos); }
    972     public void testSignalAll_awaitNanos_fair() { testSignalAll(true,  AwaitMethod.awaitNanos); }
    973     public void testSignalAll_awaitUntil()      { testSignalAll(false, AwaitMethod.awaitUntil); }
    974     public void testSignalAll_awaitUntil_fair() { testSignalAll(true,  AwaitMethod.awaitUntil); }
    975     public void testSignalAll(boolean fair, final AwaitMethod awaitMethod) {
    976         final PublicReentrantLock lock = new PublicReentrantLock(fair);
    977         final Condition c = lock.newCondition();
    978         final CountDownLatch pleaseSignal = new CountDownLatch(2);
    979         class Awaiter extends CheckedRunnable {
    980             public void realRun() throws InterruptedException {
    981                 lock.lock();
    982                 pleaseSignal.countDown();
    983                 await(c, awaitMethod);
    984                 lock.unlock();
    985             }
    986         }
    987 
    988         Thread t1 = newStartedThread(new Awaiter());
    989         Thread t2 = newStartedThread(new Awaiter());
    990 
    991         await(pleaseSignal);
    992         lock.lock();
    993         assertHasWaiters(lock, c, t1, t2);
    994         c.signalAll();
    995         assertHasNoWaiters(lock, c);
    996         lock.unlock();
    997         awaitTermination(t1);
    998         awaitTermination(t2);
    999     }
   1000 
   1001     /**
   1002      * signal wakes up waiting threads in FIFO order
   1003      */
   1004     public void testSignalWakesFifo()      { testSignalWakesFifo(false); }
   1005     public void testSignalWakesFifo_fair() { testSignalWakesFifo(true); }
   1006     public void testSignalWakesFifo(boolean fair) {
   1007         final PublicReentrantLock lock =
   1008             new PublicReentrantLock(fair);
   1009         final Condition c = lock.newCondition();
   1010         final CountDownLatch locked1 = new CountDownLatch(1);
   1011         final CountDownLatch locked2 = new CountDownLatch(1);
   1012         Thread t1 = newStartedThread(new CheckedRunnable() {
   1013             public void realRun() throws InterruptedException {
   1014                 lock.lock();
   1015                 locked1.countDown();
   1016                 c.await();
   1017                 lock.unlock();
   1018             }});
   1019 
   1020         await(locked1);
   1021 
   1022         Thread t2 = newStartedThread(new CheckedRunnable() {
   1023             public void realRun() throws InterruptedException {
   1024                 lock.lock();
   1025                 locked2.countDown();
   1026                 c.await();
   1027                 lock.unlock();
   1028             }});
   1029 
   1030         await(locked2);
   1031 
   1032         lock.lock();
   1033         assertHasWaiters(lock, c, t1, t2);
   1034         assertFalse(lock.hasQueuedThreads());
   1035         c.signal();
   1036         assertHasWaiters(lock, c, t2);
   1037         assertTrue(lock.hasQueuedThread(t1));
   1038         assertFalse(lock.hasQueuedThread(t2));
   1039         c.signal();
   1040         assertHasNoWaiters(lock, c);
   1041         assertTrue(lock.hasQueuedThread(t1));
   1042         assertTrue(lock.hasQueuedThread(t2));
   1043         lock.unlock();
   1044         awaitTermination(t1);
   1045         awaitTermination(t2);
   1046     }
   1047 
   1048     /**
   1049      * await after multiple reentrant locking preserves lock count
   1050      */
   1051     public void testAwaitLockCount()      { testAwaitLockCount(false); }
   1052     public void testAwaitLockCount_fair() { testAwaitLockCount(true); }
   1053     public void testAwaitLockCount(boolean fair) {
   1054         final PublicReentrantLock lock = new PublicReentrantLock(fair);
   1055         final Condition c = lock.newCondition();
   1056         final CountDownLatch pleaseSignal = new CountDownLatch(2);
   1057         Thread t1 = newStartedThread(new CheckedRunnable() {
   1058             public void realRun() throws InterruptedException {
   1059                 lock.lock();
   1060                 assertLockedByMoi(lock);
   1061                 assertEquals(1, lock.getHoldCount());
   1062                 pleaseSignal.countDown();
   1063                 c.await();
   1064                 assertLockedByMoi(lock);
   1065                 assertEquals(1, lock.getHoldCount());
   1066                 lock.unlock();
   1067             }});
   1068 
   1069         Thread t2 = newStartedThread(new CheckedRunnable() {
   1070             public void realRun() throws InterruptedException {
   1071                 lock.lock();
   1072                 lock.lock();
   1073                 assertLockedByMoi(lock);
   1074                 assertEquals(2, lock.getHoldCount());
   1075                 pleaseSignal.countDown();
   1076                 c.await();
   1077                 assertLockedByMoi(lock);
   1078                 assertEquals(2, lock.getHoldCount());
   1079                 lock.unlock();
   1080                 lock.unlock();
   1081             }});
   1082 
   1083         await(pleaseSignal);
   1084         lock.lock();
   1085         assertHasWaiters(lock, c, t1, t2);
   1086         assertEquals(1, lock.getHoldCount());
   1087         c.signalAll();
   1088         assertHasNoWaiters(lock, c);
   1089         lock.unlock();
   1090         awaitTermination(t1);
   1091         awaitTermination(t2);
   1092     }
   1093 
   1094     /**
   1095      * A serialized lock deserializes as unlocked
   1096      */
   1097     public void testSerialization()      { testSerialization(false); }
   1098     public void testSerialization_fair() { testSerialization(true); }
   1099     public void testSerialization(boolean fair) {
   1100         ReentrantLock lock = new ReentrantLock(fair);
   1101         lock.lock();
   1102 
   1103         ReentrantLock clone = serialClone(lock);
   1104         assertEquals(lock.isFair(), clone.isFair());
   1105         assertTrue(lock.isLocked());
   1106         assertFalse(clone.isLocked());
   1107         assertEquals(1, lock.getHoldCount());
   1108         assertEquals(0, clone.getHoldCount());
   1109         clone.lock();
   1110         clone.lock();
   1111         assertTrue(clone.isLocked());
   1112         assertEquals(2, clone.getHoldCount());
   1113         assertEquals(1, lock.getHoldCount());
   1114         clone.unlock();
   1115         clone.unlock();
   1116         assertTrue(lock.isLocked());
   1117         assertFalse(clone.isLocked());
   1118     }
   1119 
   1120     /**
   1121      * toString indicates current lock state
   1122      */
   1123     public void testToString()      { testToString(false); }
   1124     public void testToString_fair() { testToString(true); }
   1125     public void testToString(boolean fair) {
   1126         ReentrantLock lock = new ReentrantLock(fair);
   1127         assertTrue(lock.toString().contains("Unlocked"));
   1128         lock.lock();
   1129         assertTrue(lock.toString().contains("Locked"));
   1130         lock.unlock();
   1131         assertTrue(lock.toString().contains("Unlocked"));
   1132     }
   1133 }
   1134