--- jsr166/src/test/tck/CyclicBarrierTest.java 2011/05/15 16:56:41 1.19 +++ jsr166/src/test/tck/CyclicBarrierTest.java 2014/12/31 19:05:42 1.26 @@ -6,13 +6,17 @@ * Pat Fisher, Mike Judd. */ -import junit.framework.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.locks.*; -import java.util.concurrent.atomic.*; import static java.util.concurrent.TimeUnit.MILLISECONDS; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicBoolean; + +import junit.framework.Test; +import junit.framework.TestSuite; + public class CyclicBarrierTest extends JSR166TestCase { public static void main(String[] args) { junit.textui.TestRunner.run(suite()); @@ -27,6 +31,18 @@ public class CyclicBarrierTest extends J } /** + * Spin-waits till the number of waiters == numberOfWaiters. + */ + void awaitNumberWaiting(CyclicBarrier barrier, int numberOfWaiters) { + long startTime = System.nanoTime(); + while (barrier.getNumberWaiting() != numberOfWaiters) { + if (millisElapsedSince(startTime) > LONG_DELAY_MS) + fail("timed out"); + Thread.yield(); + } + } + + /** * Creating with negative parties throws IAE */ public void testConstructor1() { @@ -78,7 +94,7 @@ public class CyclicBarrierTest extends J b.await(); b.await(); assertEquals(0, b.getNumberWaiting()); - assertEquals(countAction, 2); + assertEquals(2, countAction); } /** @@ -86,7 +102,7 @@ public class CyclicBarrierTest extends J */ public void testTwoParties() throws Exception { final CyclicBarrier b = new CyclicBarrier(2); - Thread t = new Thread(new CheckedRunnable() { + Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws Exception { b.await(); b.await(); @@ -94,36 +110,37 @@ public class CyclicBarrierTest extends J b.await(); }}); - t.start(); b.await(); b.await(); b.await(); b.await(); - t.join(); + awaitTermination(t); } - /** * An interruption in one party causes others waiting in await to * throw BrokenBarrierException */ - public void testAwait1_Interrupted_BrokenBarrier() throws Exception { + public void testAwait1_Interrupted_BrokenBarrier() { final CyclicBarrier c = new CyclicBarrier(3); + final CountDownLatch pleaseInterrupt = new CountDownLatch(2); Thread t1 = new ThreadShouldThrow(InterruptedException.class) { public void realRun() throws Exception { + pleaseInterrupt.countDown(); c.await(); }}; Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) { public void realRun() throws Exception { + pleaseInterrupt.countDown(); c.await(); }}; t1.start(); t2.start(); - delay(SHORT_DELAY_MS); + await(pleaseInterrupt); t1.interrupt(); - t1.join(); - t2.join(); + awaitTermination(t1); + awaitTermination(t2); } /** @@ -132,21 +149,24 @@ public class CyclicBarrierTest extends J */ public void testAwait2_Interrupted_BrokenBarrier() throws Exception { final CyclicBarrier c = new CyclicBarrier(3); + final CountDownLatch pleaseInterrupt = new CountDownLatch(2); Thread t1 = new ThreadShouldThrow(InterruptedException.class) { public void realRun() throws Exception { + pleaseInterrupt.countDown(); c.await(LONG_DELAY_MS, MILLISECONDS); }}; Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) { public void realRun() throws Exception { + pleaseInterrupt.countDown(); c.await(LONG_DELAY_MS, MILLISECONDS); }}; t1.start(); t2.start(); - delay(SHORT_DELAY_MS); + await(pleaseInterrupt); t1.interrupt(); - t1.join(); - t2.join(); + awaitTermination(t1); + awaitTermination(t2); } /** @@ -154,13 +174,17 @@ public class CyclicBarrierTest extends J */ public void testAwait3_TimeoutException() throws InterruptedException { final CyclicBarrier c = new CyclicBarrier(2); - Thread t = new ThreadShouldThrow(TimeoutException.class) { + Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws Exception { - c.await(SHORT_DELAY_MS, MILLISECONDS); - }}; + long startTime = System.nanoTime(); + try { + c.await(timeoutMillis(), MILLISECONDS); + shouldThrow(); + } catch (TimeoutException success) {} + assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); + }}); - t.start(); - t.join(); + awaitTermination(t); } /** @@ -169,19 +193,26 @@ public class CyclicBarrierTest extends J */ public void testAwait4_Timeout_BrokenBarrier() throws InterruptedException { final CyclicBarrier c = new CyclicBarrier(3); - Thread t1 = new ThreadShouldThrow(TimeoutException.class) { + Thread t1 = newStartedThread(new CheckedRunnable() { public void realRun() throws Exception { - c.await(SHORT_DELAY_MS, MILLISECONDS); - }}; - Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) { + try { + c.await(LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (BrokenBarrierException success) {} + }}); + Thread t2 = newStartedThread(new CheckedRunnable() { public void realRun() throws Exception { - c.await(MEDIUM_DELAY_MS, MILLISECONDS); - }}; + awaitNumberWaiting(c, 1); + long startTime = System.nanoTime(); + try { + c.await(timeoutMillis(), MILLISECONDS); + shouldThrow(); + } catch (TimeoutException success) {} + assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); + }}); - t1.start(); - t2.start(); - t1.join(); - t2.join(); + awaitTermination(t1); + awaitTermination(t2); } /** @@ -190,19 +221,26 @@ public class CyclicBarrierTest extends J */ public void testAwait5_Timeout_BrokenBarrier() throws InterruptedException { final CyclicBarrier c = new CyclicBarrier(3); - Thread t1 = new ThreadShouldThrow(TimeoutException.class) { + Thread t1 = newStartedThread(new CheckedRunnable() { public void realRun() throws Exception { - c.await(SHORT_DELAY_MS, MILLISECONDS); - }}; - Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) { + try { + c.await(); + shouldThrow(); + } catch (BrokenBarrierException success) {} + }}); + Thread t2 = newStartedThread(new CheckedRunnable() { public void realRun() throws Exception { - c.await(); - }}; + awaitNumberWaiting(c, 1); + long startTime = System.nanoTime(); + try { + c.await(timeoutMillis(), MILLISECONDS); + shouldThrow(); + } catch (TimeoutException success) {} + assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); + }}); - t1.start(); - t2.start(); - t1.join(); - t2.join(); + awaitTermination(t1); + awaitTermination(t2); } /** @@ -211,21 +249,26 @@ public class CyclicBarrierTest extends J */ public void testReset_BrokenBarrier() throws InterruptedException { final CyclicBarrier c = new CyclicBarrier(3); + final CountDownLatch pleaseReset = new CountDownLatch(2); Thread t1 = new ThreadShouldThrow(BrokenBarrierException.class) { public void realRun() throws Exception { + pleaseReset.countDown(); c.await(); }}; Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) { public void realRun() throws Exception { + pleaseReset.countDown(); c.await(); }}; t1.start(); t2.start(); - delay(SHORT_DELAY_MS); + await(pleaseReset); + + awaitNumberWaiting(c, 2); c.reset(); - t1.join(); - t2.join(); + awaitTermination(t1); + awaitTermination(t2); } /** @@ -234,21 +277,20 @@ public class CyclicBarrierTest extends J */ public void testReset_NoBrokenBarrier() throws Exception { final CyclicBarrier c = new CyclicBarrier(3); - Thread t1 = new Thread(new CheckedRunnable() { + c.reset(); + + Thread t1 = newStartedThread(new CheckedRunnable() { public void realRun() throws Exception { c.await(); }}); - Thread t2 = new Thread(new CheckedRunnable() { + Thread t2 = newStartedThread(new CheckedRunnable() { public void realRun() throws Exception { c.await(); }}); - c.reset(); - t1.start(); - t2.start(); c.await(); - t1.join(); - t2.join(); + awaitTermination(t1); + awaitTermination(t2); } /** @@ -257,59 +299,52 @@ public class CyclicBarrierTest extends J public void testReset_Leakage() throws InterruptedException { final CyclicBarrier c = new CyclicBarrier(2); final AtomicBoolean done = new AtomicBoolean(); - Thread t = new Thread() { - public void run() { - while (!done.get()) { - try { - while (c.isBroken()) - c.reset(); - - c.await(); - threadFail("await should not return"); - } - catch (BrokenBarrierException e) { - } - catch (InterruptedException ie) { - } + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() { + while (!done.get()) { + try { + while (c.isBroken()) + c.reset(); + + c.await(); + shouldThrow(); } - } - }; + catch (BrokenBarrierException ok) {} + catch (InterruptedException ok) {} + }}}); - t.start(); for (int i = 0; i < 4; i++) { - delay(SHORT_DELAY_MS); + delay(timeoutMillis()); t.interrupt(); } done.set(true); t.interrupt(); - t.join(); + awaitTermination(t); } /** * Reset of a non-broken barrier does not break barrier */ public void testResetWithoutBreakage() throws Exception { - final CyclicBarrier start = new CyclicBarrier(3); final CyclicBarrier barrier = new CyclicBarrier(3); for (int i = 0; i < 3; i++) { - Thread t1 = new Thread(new CheckedRunnable() { + final CyclicBarrier start = new CyclicBarrier(3); + Thread t1 = newStartedThread(new CheckedRunnable() { public void realRun() throws Exception { start.await(); barrier.await(); }}); - Thread t2 = new Thread(new CheckedRunnable() { + Thread t2 = newStartedThread(new CheckedRunnable() { public void realRun() throws Exception { start.await(); barrier.await(); }}); - t1.start(); - t2.start(); start.await(); barrier.await(); - t1.join(); - t2.join(); + awaitTermination(t1); + awaitTermination(t2); assertFalse(barrier.isBroken()); assertEquals(0, barrier.getNumberWaiting()); if (i == 1) barrier.reset(); @@ -322,9 +357,9 @@ public class CyclicBarrierTest extends J * Reset of a barrier after interruption reinitializes it. */ public void testResetAfterInterrupt() throws Exception { - final CyclicBarrier start = new CyclicBarrier(3); final CyclicBarrier barrier = new CyclicBarrier(3); for (int i = 0; i < 2; i++) { + final CyclicBarrier start = new CyclicBarrier(3); Thread t1 = new ThreadShouldThrow(InterruptedException.class) { public void realRun() throws Exception { start.await(); @@ -341,8 +376,8 @@ public class CyclicBarrierTest extends J t2.start(); start.await(); t1.interrupt(); - t1.join(); - t2.join(); + awaitTermination(t1); + awaitTermination(t2); assertTrue(barrier.isBroken()); assertEquals(0, barrier.getNumberWaiting()); barrier.reset(); @@ -355,25 +390,30 @@ public class CyclicBarrierTest extends J * Reset of a barrier after timeout reinitializes it. */ public void testResetAfterTimeout() throws Exception { - final CyclicBarrier start = new CyclicBarrier(2); final CyclicBarrier barrier = new CyclicBarrier(3); for (int i = 0; i < 2; i++) { - Thread t1 = new ThreadShouldThrow(TimeoutException.class) { - public void realRun() throws Exception { - start.await(); - barrier.await(SHORT_DELAY_MS, MILLISECONDS); - }}; - - Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) { + assertEquals(0, barrier.getNumberWaiting()); + Thread t1 = newStartedThread(new CheckedRunnable() { public void realRun() throws Exception { - start.await(); - barrier.await(); - }}; + try { + barrier.await(); + shouldThrow(); + } catch (BrokenBarrierException success) {} + }}); + Thread t2 = newStartedThread(new CheckedRunnable() { + public void realRun() throws Exception { + awaitNumberWaiting(barrier, 1); + long startTime = System.nanoTime(); + try { + barrier.await(timeoutMillis(), MILLISECONDS); + shouldThrow(); + } catch (TimeoutException success) {} + assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); + }}); - t1.start(); - t2.start(); - t1.join(); - t2.join(); + awaitTermination(t1); + awaitTermination(t2); + assertEquals(0, barrier.getNumberWaiting()); assertTrue(barrier.isBroken()); assertEquals(0, barrier.getNumberWaiting()); barrier.reset(); @@ -382,17 +422,16 @@ public class CyclicBarrierTest extends J } } - /** * Reset of a barrier after a failed command reinitializes it. */ public void testResetAfterCommandException() throws Exception { - final CyclicBarrier start = new CyclicBarrier(3); final CyclicBarrier barrier = new CyclicBarrier(3, new Runnable() { public void run() { throw new NullPointerException(); }}); for (int i = 0; i < 2; i++) { + final CyclicBarrier start = new CyclicBarrier(3); Thread t1 = new ThreadShouldThrow(BrokenBarrierException.class) { public void realRun() throws Exception { start.await(); @@ -408,13 +447,13 @@ public class CyclicBarrierTest extends J t1.start(); t2.start(); start.await(); - while (barrier.getNumberWaiting() < 2) { Thread.yield(); } + awaitNumberWaiting(barrier, 2); try { barrier.await(); shouldThrow(); } catch (NullPointerException success) {} - t1.join(); - t2.join(); + awaitTermination(t1); + awaitTermination(t2); assertTrue(barrier.isBroken()); assertEquals(0, barrier.getNumberWaiting()); barrier.reset();