--- jsr166/src/test/tck/ReentrantLockTest.java 2011/05/13 21:48:59 1.46 +++ jsr166/src/test/tck/ReentrantLockTest.java 2015/02/27 21:43:18 1.57 @@ -6,12 +6,19 @@ * Pat Fisher, Mike Judd. */ -import junit.framework.*; -import java.util.concurrent.locks.*; -import java.util.concurrent.*; import static java.util.concurrent.TimeUnit.MILLISECONDS; -import java.util.*; -import java.io.*; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import junit.framework.AssertionFailedError; +import junit.framework.Test; +import junit.framework.TestSuite; public class ReentrantLockTest extends JSR166TestCase { public static void main(String[] args) { @@ -22,23 +29,23 @@ public class ReentrantLockTest extends J } /** - * A runnable calling lockInterruptibly + * A checked runnable calling lockInterruptibly */ class InterruptibleLockRunnable extends CheckedRunnable { final ReentrantLock lock; - InterruptibleLockRunnable(ReentrantLock l) { lock = l; } + InterruptibleLockRunnable(ReentrantLock lock) { this.lock = lock; } public void realRun() throws InterruptedException { lock.lockInterruptibly(); } } /** - * A runnable calling lockInterruptibly that expects to be + * A checked runnable calling lockInterruptibly that expects to be * interrupted */ class InterruptedLockRunnable extends CheckedInterruptedRunnable { final ReentrantLock lock; - InterruptedLockRunnable(ReentrantLock l) { lock = l; } + InterruptedLockRunnable(ReentrantLock lock) { this.lock = lock; } public void realRun() throws InterruptedException { lock.lockInterruptibly(); } @@ -78,11 +85,11 @@ public class ReentrantLockTest extends J long startTime = System.nanoTime(); while (!lock.hasQueuedThread(t)) { if (millisElapsedSince(startTime) > LONG_DELAY_MS) - throw new AssertionError("timed out"); + throw new AssertionFailedError("timed out"); Thread.yield(); } assertTrue(t.isAlive()); - assertTrue(lock.getOwner() != t); + assertNotSame(t, lock.getOwner()); } /** @@ -136,25 +143,31 @@ public class ReentrantLockTest extends J lock.unlock(); } - enum AwaitMethod { await, awaitNanos, awaitUntil }; + enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil } /** * Awaits condition using the specified AwaitMethod. */ void await(Condition c, AwaitMethod awaitMethod) throws InterruptedException { + long timeoutMillis = 2 * LONG_DELAY_MS; switch (awaitMethod) { case await: c.await(); break; + case awaitTimed: + assertTrue(c.await(timeoutMillis, MILLISECONDS)); + break; case awaitNanos: - long nanosRemaining = c.awaitNanos(MILLISECONDS.toNanos(2 * LONG_DELAY_MS)); + long nanosTimeout = MILLISECONDS.toNanos(timeoutMillis); + long nanosRemaining = c.awaitNanos(nanosTimeout); assertTrue(nanosRemaining > 0); break; case awaitUntil: - java.util.Date d = new java.util.Date(); - assertTrue(c.awaitUntil(new java.util.Date(d.getTime() + 2 * LONG_DELAY_MS))); + assertTrue(c.awaitUntil(delayedDate(timeoutMillis))); break; + default: + throw new AssertionError(); } } @@ -282,7 +295,7 @@ public class ReentrantLockTest extends J } /** - * hasQueuedThread reports whether a thread is queued. + * hasQueuedThread reports whether a thread is queued */ public void testHasQueuedThread() { testHasQueuedThread(false); } public void testHasQueuedThread_fair() { testHasQueuedThread(true); } @@ -343,7 +356,7 @@ public class ReentrantLockTest extends J } /** - * timed tryLock is interruptible. + * timed tryLock is interruptible */ public void testTryLock_Interruptible() { testTryLock_Interruptible(false); } public void testTryLock_Interruptible_fair() { testTryLock_Interruptible(true); } @@ -447,9 +460,7 @@ public class ReentrantLockTest extends J barrier.await(); awaitTermination(t); assertFalse(lock.isLocked()); - } catch (Exception e) { - threadUnexpectedException(e); - } + } catch (Exception fail) { threadUnexpectedException(fail); } } /** @@ -461,9 +472,7 @@ public class ReentrantLockTest extends J final PublicReentrantLock lock = new PublicReentrantLock(fair); try { lock.lockInterruptibly(); - } catch (InterruptedException ie) { - threadUnexpectedException(ie); - } + } catch (InterruptedException fail) { threadUnexpectedException(fail); } assertLockedByMoi(lock); Thread t = newStartedThread(new InterruptedLockRunnable(lock)); waitForQueuedThread(lock, t); @@ -482,28 +491,15 @@ public class ReentrantLockTest extends J public void testAwait_IMSE(boolean fair) { final ReentrantLock lock = new ReentrantLock(fair); final Condition c = lock.newCondition(); - long startTime = System.nanoTime(); - try { - try { - c.await(); - shouldThrow(); - } catch (IllegalMonitorStateException success) {} - try { - c.await(LONG_DELAY_MS, MILLISECONDS); - shouldThrow(); - } catch (IllegalMonitorStateException success) {} - try { - c.awaitNanos(MILLISECONDS.toNanos(LONG_DELAY_MS)); - shouldThrow(); - } catch (IllegalMonitorStateException success) {} + for (AwaitMethod awaitMethod : AwaitMethod.values()) { + long startTime = System.nanoTime(); try { - c.awaitUninterruptibly(); + await(c, awaitMethod); shouldThrow(); - } catch (IllegalMonitorStateException success) {} - } catch (InterruptedException ie) { - threadUnexpectedException(ie); + } catch (IllegalMonitorStateException success) { + } catch (InterruptedException e) { threadUnexpectedException(e); } + assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); } - assertTrue(millisElapsedSince(startTime) < MEDIUM_DELAY_MS); } /** @@ -537,9 +533,7 @@ public class ReentrantLockTest extends J assertTrue(nanosRemaining <= 0); assertTrue(millisElapsedSince(startTime) >= timeoutMillis); lock.unlock(); - } catch (InterruptedException e) { - threadUnexpectedException(e); - } + } catch (InterruptedException fail) { threadUnexpectedException(fail); } } /** @@ -557,9 +551,7 @@ public class ReentrantLockTest extends J assertFalse(c.await(timeoutMillis, MILLISECONDS)); assertTrue(millisElapsedSince(startTime) >= timeoutMillis); lock.unlock(); - } catch (InterruptedException e) { - threadUnexpectedException(e); - } + } catch (InterruptedException fail) { threadUnexpectedException(fail); } } /** @@ -578,9 +570,7 @@ public class ReentrantLockTest extends J assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + timeoutMillis))); assertTrue(millisElapsedSince(startTime) >= timeoutMillis); lock.unlock(); - } catch (InterruptedException e) { - threadUnexpectedException(e); - } + } catch (InterruptedException fail) { threadUnexpectedException(fail); } } /** @@ -744,20 +734,20 @@ public class ReentrantLockTest extends J public void testHasWaiters(boolean fair) { final PublicReentrantLock lock = new PublicReentrantLock(fair); final Condition c = lock.newCondition(); - final CountDownLatch locked = new CountDownLatch(1); + final CountDownLatch pleaseSignal = new CountDownLatch(1); Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { lock.lock(); assertHasNoWaiters(lock, c); assertFalse(lock.hasWaiters(c)); - locked.countDown(); + pleaseSignal.countDown(); c.await(); assertHasNoWaiters(lock, c); assertFalse(lock.hasWaiters(c)); lock.unlock(); }}); - await(locked); + await(pleaseSignal); lock.lock(); assertHasWaiters(lock, c, t); assertTrue(lock.hasWaiters(c)); @@ -888,33 +878,50 @@ public class ReentrantLockTest extends J } /** - * awaitUninterruptibly doesn't abort on interrupt + * awaitUninterruptibly is uninterruptible */ public void testAwaitUninterruptibly() { testAwaitUninterruptibly(false); } public void testAwaitUninterruptibly_fair() { testAwaitUninterruptibly(true); } public void testAwaitUninterruptibly(boolean fair) { final ReentrantLock lock = new ReentrantLock(fair); final Condition c = lock.newCondition(); - final CountDownLatch locked = new CountDownLatch(1); - Thread t = newStartedThread(new CheckedRunnable() { + final CountDownLatch pleaseInterrupt = new CountDownLatch(2); + + Thread t1 = newStartedThread(new CheckedRunnable() { public void realRun() { + // Interrupt before awaitUninterruptibly lock.lock(); - locked.countDown(); + pleaseInterrupt.countDown(); + Thread.currentThread().interrupt(); c.awaitUninterruptibly(); assertTrue(Thread.interrupted()); lock.unlock(); }}); - await(locked); + Thread t2 = newStartedThread(new CheckedRunnable() { + public void realRun() { + // Interrupt during awaitUninterruptibly + lock.lock(); + pleaseInterrupt.countDown(); + c.awaitUninterruptibly(); + assertTrue(Thread.interrupted()); + lock.unlock(); + }}); + + await(pleaseInterrupt); lock.lock(); lock.unlock(); - t.interrupt(); - long timeoutMillis = 10; - assertThreadStaysAlive(t, timeoutMillis); + t2.interrupt(); + + assertThreadStaysAlive(t1); + assertTrue(t2.isAlive()); + lock.lock(); - c.signal(); + c.signalAll(); lock.unlock(); - awaitTermination(t); + + awaitTermination(t1); + awaitTermination(t2); } /** @@ -922,6 +929,8 @@ public class ReentrantLockTest extends J */ public void testInterruptible_await() { testInterruptible(false, AwaitMethod.await); } public void testInterruptible_await_fair() { testInterruptible(true, AwaitMethod.await); } + public void testInterruptible_awaitTimed() { testInterruptible(false, AwaitMethod.awaitTimed); } + public void testInterruptible_awaitTimed_fair() { testInterruptible(true, AwaitMethod.awaitTimed); } public void testInterruptible_awaitNanos() { testInterruptible(false, AwaitMethod.awaitNanos); } public void testInterruptible_awaitNanos_fair() { testInterruptible(true, AwaitMethod.awaitNanos); } public void testInterruptible_awaitUntil() { testInterruptible(false, AwaitMethod.awaitUntil); } @@ -930,13 +939,13 @@ public class ReentrantLockTest extends J final PublicReentrantLock lock = new PublicReentrantLock(fair); final Condition c = lock.newCondition(); - final CountDownLatch locked = new CountDownLatch(1); + final CountDownLatch pleaseInterrupt = new CountDownLatch(1); Thread t = newStartedThread(new CheckedInterruptedRunnable() { public void realRun() throws InterruptedException { lock.lock(); assertLockedByMoi(lock); assertHasNoWaiters(lock, c); - locked.countDown(); + pleaseInterrupt.countDown(); try { await(c, awaitMethod); } finally { @@ -947,7 +956,7 @@ public class ReentrantLockTest extends J } }}); - await(locked); + await(pleaseInterrupt); assertHasWaiters(lock, c, t); t.interrupt(); awaitTermination(t); @@ -959,6 +968,8 @@ public class ReentrantLockTest extends J */ public void testSignalAll_await() { testSignalAll(false, AwaitMethod.await); } public void testSignalAll_await_fair() { testSignalAll(true, AwaitMethod.await); } + public void testSignalAll_awaitTimed() { testSignalAll(false, AwaitMethod.awaitTimed); } + public void testSignalAll_awaitTimed_fair() { testSignalAll(true, AwaitMethod.awaitTimed); } public void testSignalAll_awaitNanos() { testSignalAll(false, AwaitMethod.awaitNanos); } public void testSignalAll_awaitNanos_fair() { testSignalAll(true, AwaitMethod.awaitNanos); } public void testSignalAll_awaitUntil() { testSignalAll(false, AwaitMethod.awaitUntil); } @@ -966,11 +977,11 @@ public class ReentrantLockTest extends J public void testSignalAll(boolean fair, final AwaitMethod awaitMethod) { final PublicReentrantLock lock = new PublicReentrantLock(fair); final Condition c = lock.newCondition(); - final CountDownLatch locked = new CountDownLatch(2); + final CountDownLatch pleaseSignal = new CountDownLatch(2); class Awaiter extends CheckedRunnable { public void realRun() throws InterruptedException { lock.lock(); - locked.countDown(); + pleaseSignal.countDown(); await(c, awaitMethod); lock.unlock(); } @@ -979,7 +990,7 @@ public class ReentrantLockTest extends J Thread t1 = newStartedThread(new Awaiter()); Thread t2 = newStartedThread(new Awaiter()); - await(locked); + await(pleaseSignal); lock.lock(); assertHasWaiters(lock, c, t1, t2); c.signalAll(); @@ -990,7 +1001,7 @@ public class ReentrantLockTest extends J } /** - * signal wakes up waiting threads in FIFO order. + * signal wakes up waiting threads in FIFO order */ public void testSignalWakesFifo() { testSignalWakesFifo(false); } public void testSignalWakesFifo_fair() { testSignalWakesFifo(true); } @@ -1044,13 +1055,13 @@ public class ReentrantLockTest extends J public void testAwaitLockCount(boolean fair) { final PublicReentrantLock lock = new PublicReentrantLock(fair); final Condition c = lock.newCondition(); - final CountDownLatch locked = new CountDownLatch(2); + final CountDownLatch pleaseSignal = new CountDownLatch(2); Thread t1 = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { lock.lock(); assertLockedByMoi(lock); assertEquals(1, lock.getHoldCount()); - locked.countDown(); + pleaseSignal.countDown(); c.await(); assertLockedByMoi(lock); assertEquals(1, lock.getHoldCount()); @@ -1063,7 +1074,7 @@ public class ReentrantLockTest extends J lock.lock(); assertLockedByMoi(lock); assertEquals(2, lock.getHoldCount()); - locked.countDown(); + pleaseSignal.countDown(); c.await(); assertLockedByMoi(lock); assertEquals(2, lock.getHoldCount()); @@ -1071,7 +1082,7 @@ public class ReentrantLockTest extends J lock.unlock(); }}); - await(locked); + await(pleaseSignal); lock.lock(); assertHasWaiters(lock, c, t1, t2); assertEquals(1, lock.getHoldCount()); @@ -1115,10 +1126,10 @@ public class ReentrantLockTest extends J public void testToString_fair() { testToString(true); } public void testToString(boolean fair) { ReentrantLock lock = new ReentrantLock(fair); - String us = lock.toString(); - assertTrue(us.indexOf("Unlocked") >= 0); + assertTrue(lock.toString().contains("Unlocked")); lock.lock(); - String ls = lock.toString(); - assertTrue(ls.indexOf("Locked") >= 0); + assertTrue(lock.toString().contains("Locked")); + lock.unlock(); + assertTrue(lock.toString().contains("Unlocked")); } }