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