--- jsr166/src/test/tck/SemaphoreTest.java 2014/12/31 19:05:43 1.32 +++ jsr166/src/test/tck/SemaphoreTest.java 2019/08/13 00:46:27 1.45 @@ -12,13 +12,12 @@ import java.util.Collection; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Semaphore; -import junit.framework.AssertionFailedError; import junit.framework.Test; import junit.framework.TestSuite; public class SemaphoreTest extends JSR166TestCase { public static void main(String[] args) { - junit.textui.TestRunner.run(suite()); + main(suite(), args); } public static Test suite() { return new TestSuite(SemaphoreTest.class); @@ -73,7 +72,7 @@ public class SemaphoreTest extends JSR16 long startTime = System.nanoTime(); while (!s.hasQueuedThread(t)) { if (millisElapsedSince(startTime) > LONG_DELAY_MS) - throw new AssertionFailedError("timed out"); + throw new AssertionError("timed out"); Thread.yield(); } assertTrue(s.hasQueuedThreads()); @@ -87,7 +86,7 @@ public class SemaphoreTest extends JSR16 long startTime = System.nanoTime(); while (!s.hasQueuedThreads()) { if (millisElapsedSince(startTime) > LONG_DELAY_MS) - throw new AssertionFailedError("timed out"); + throw new AssertionError("timed out"); Thread.yield(); } } @@ -127,11 +126,13 @@ public class SemaphoreTest extends JSR16 void acquire(Semaphore s) throws InterruptedException { assertTrue(s.tryAcquire(2 * LONG_DELAY_MS, MILLISECONDS)); } + Thread.State parkedState() { return Thread.State.TIMED_WAITING; } }, tryAcquireTimedN { void acquire(Semaphore s, int permits) throws InterruptedException { assertTrue(s.tryAcquire(permits, 2 * LONG_DELAY_MS, MILLISECONDS)); } + Thread.State parkedState() { return Thread.State.TIMED_WAITING; } }; // Intentionally meta-circular @@ -145,6 +146,7 @@ public class SemaphoreTest extends JSR16 for (int i = 0; i < permits; i++) acquire(s); } + Thread.State parkedState() { return Thread.State.WAITING; } } /** @@ -190,26 +192,22 @@ public class SemaphoreTest extends JSR16 /** * timed tryAcquire times out */ - public void testTryAcquire_timeout() { testTryAcquire_timeout(false); } - public void testTryAcquire_timeout_fair() { testTryAcquire_timeout(true); } - public void testTryAcquire_timeout(boolean fair) { - Semaphore s = new Semaphore(0, fair); - long startTime = System.nanoTime(); - try { assertFalse(s.tryAcquire(timeoutMillis(), MILLISECONDS)); } - catch (InterruptedException e) { threadUnexpectedException(e); } + public void testTryAcquire_timeout() throws InterruptedException { + final boolean fair = randomBoolean(); + final Semaphore s = new Semaphore(0, fair); + final long startTime = System.nanoTime(); + assertFalse(s.tryAcquire(timeoutMillis(), MILLISECONDS)); assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); } /** * timed tryAcquire(N) times out */ - public void testTryAcquireN_timeout() { testTryAcquireN_timeout(false); } - public void testTryAcquireN_timeout_fair() { testTryAcquireN_timeout(true); } - public void testTryAcquireN_timeout(boolean fair) { - Semaphore s = new Semaphore(2, fair); - long startTime = System.nanoTime(); - try { assertFalse(s.tryAcquire(3, timeoutMillis(), MILLISECONDS)); } - catch (InterruptedException e) { threadUnexpectedException(e); } + public void testTryAcquireN_timeout() throws InterruptedException { + final boolean fair = randomBoolean(); + final Semaphore s = new Semaphore(2, fair); + final long startTime = System.nanoTime(); + assertFalse(s.tryAcquire(3, timeoutMillis(), MILLISECONDS)); assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); } @@ -227,7 +225,8 @@ public class SemaphoreTest extends JSR16 public void testInterruptible_tryAcquireTimedN_fair() { testInterruptible(true, AcquireMethod.tryAcquireTimedN); } public void testInterruptible(boolean fair, final AcquireMethod acquirer) { final PublicSemaphore s = new PublicSemaphore(0, fair); - final Semaphore pleaseInterrupt = new Semaphore(0, fair); + final java.util.concurrent.CyclicBarrier pleaseInterrupt + = new java.util.concurrent.CyclicBarrier(2); Thread t = newStartedThread(new CheckedRunnable() { public void realRun() { // Interrupt before acquire @@ -236,12 +235,7 @@ public class SemaphoreTest extends JSR16 acquirer.acquire(s); shouldThrow(); } catch (InterruptedException success) {} - - // Interrupt during acquire - try { - acquirer.acquire(s); - shouldThrow(); - } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); // Interrupt before acquire(N) Thread.currentThread().interrupt(); @@ -249,21 +243,31 @@ public class SemaphoreTest extends JSR16 acquirer.acquire(s, 3); shouldThrow(); } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); - pleaseInterrupt.release(); + // Interrupt during acquire + await(pleaseInterrupt); + try { + acquirer.acquire(s); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); // Interrupt during acquire(N) + await(pleaseInterrupt); try { acquirer.acquire(s, 3); shouldThrow(); } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); }}); - waitForQueuedThread(s, t); - t.interrupt(); - await(pleaseInterrupt); - waitForQueuedThread(s, t); - t.interrupt(); + for (int n = 2; n-->0; ) { + await(pleaseInterrupt); + assertThreadBlocks(t, acquirer.parkedState()); + t.interrupt(); + } + awaitTermination(t); } @@ -301,8 +305,8 @@ public class SemaphoreTest extends JSR16 waitForQueuedThread(s, t2); t2.interrupt(); - assertThreadStaysAlive(t1); - assertTrue(t2.isAlive()); + assertThreadBlocks(t1, Thread.State.WAITING); + assertThreadBlocks(t2, Thread.State.WAITING); s.release(2); @@ -467,11 +471,16 @@ public class SemaphoreTest extends JSR16 clone.release(); assertEquals(2, s.availablePermits()); assertEquals(1, clone.availablePermits()); + assertFalse(s.hasQueuedThreads()); + assertFalse(clone.hasQueuedThreads()); + } catch (InterruptedException e) { threadUnexpectedException(e); } - s = new Semaphore(0, fair); + { + PublicSemaphore s = new PublicSemaphore(0, fair); Thread t = newStartedThread(new InterruptibleLockRunnable(s)); - waitForQueuedThreads(s); - clone = serialClone(s); + // waitForQueuedThreads(s); // suffers from "flicker", so ... + waitForQueuedThread(s, t); // ... we use this instead + PublicSemaphore clone = serialClone(s); assertEquals(fair, s.isFair()); assertEquals(fair, clone.isFair()); assertEquals(0, s.availablePermits()); @@ -482,7 +491,7 @@ public class SemaphoreTest extends JSR16 awaitTermination(t); assertFalse(s.hasQueuedThreads()); assertFalse(clone.hasQueuedThreads()); - } catch (InterruptedException e) { threadUnexpectedException(e); } + } } /** @@ -590,13 +599,15 @@ public class SemaphoreTest extends JSR16 s.acquire(3); }}); - waitForQueuedThreads(s); + waitForQueuedThread(s, t1); Thread t2 = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { // Will fail, even though 1 permit is available - assertFalse(s.tryAcquire(0L, MILLISECONDS)); - assertFalse(s.tryAcquire(1, 0L, MILLISECONDS)); + assertFalse( + s.tryAcquire(randomExpiredTimeout(), randomTimeUnit())); + assertFalse( + s.tryAcquire(1, randomExpiredTimeout(), randomTimeUnit())); // untimed tryAcquire will barge and succeed assertTrue(s.tryAcquire()); @@ -616,7 +627,7 @@ public class SemaphoreTest extends JSR16 assertTrue(t2.isAlive()); s.release(); awaitTermination(t2); - } + } /** * toString indicates current number of permits