--- jsr166/src/test/tck/CyclicBarrierTest.java 2004/01/09 14:45:58 1.7 +++ jsr166/src/test/tck/CyclicBarrierTest.java 2009/11/21 02:07:26 1.12 @@ -2,27 +2,29 @@ * Written by Doug Lea with assistance from members of JCP JSR-166 * Expert Group and released to the public domain, as explained at * http://creativecommons.org/licenses/publicdomain - * Other contributors include Andrew Wright, Jeffrey Hayes, - * Pat Fisher, Mike Judd. + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. */ import junit.framework.*; import java.util.*; import java.util.concurrent.*; +import java.util.concurrent.locks.*; +import java.util.concurrent.atomic.*; -public class CyclicBarrierTest extends JSR166TestCase{ +public class CyclicBarrierTest extends JSR166TestCase { public static void main(String[] args) { - junit.textui.TestRunner.run (suite()); + junit.textui.TestRunner.run (suite()); } public static Test suite() { - return new TestSuite(CyclicBarrierTest.class); + return new TestSuite(CyclicBarrierTest.class); } private volatile int countAction; private class MyAction implements Runnable { public void run() { ++countAction; } } - + /** * Creating with negative parties throws IAE */ @@ -30,7 +32,7 @@ public class CyclicBarrierTest extends J try { new CyclicBarrier(-1, (Runnable)null); shouldThrow(); - } catch(IllegalArgumentException e){} + } catch (IllegalArgumentException e) {} } /** @@ -40,7 +42,7 @@ public class CyclicBarrierTest extends J try { new CyclicBarrier(-1); shouldThrow(); - } catch(IllegalArgumentException e){} + } catch (IllegalArgumentException e) {} } /** @@ -48,7 +50,7 @@ public class CyclicBarrierTest extends J */ public void testGetParties() { CyclicBarrier b = new CyclicBarrier(2); - assertEquals(2, b.getParties()); + assertEquals(2, b.getParties()); assertEquals(0, b.getNumberWaiting()); } @@ -64,11 +66,11 @@ public class CyclicBarrierTest extends J b.await(); assertEquals(0, b.getNumberWaiting()); } - catch(Exception e) { + catch (Exception e) { unexpectedException(); } } - + /** * The supplied barrier action is run at barrier */ @@ -83,7 +85,7 @@ public class CyclicBarrierTest extends J assertEquals(0, b.getNumberWaiting()); assertEquals(countAction, 2); } - catch(Exception e) { + catch (Exception e) { unexpectedException(); } } @@ -93,14 +95,14 @@ public class CyclicBarrierTest extends J */ public void testTwoParties() { final CyclicBarrier b = new CyclicBarrier(2); - Thread t = new Thread(new Runnable() { - public void run() { + Thread t = new Thread(new Runnable() { + public void run() { try { b.await(); b.await(); b.await(); b.await(); - } catch(Exception e){ + } catch (Exception e) { threadUnexpectedException(); }}}); @@ -111,7 +113,7 @@ public class CyclicBarrierTest extends J b.await(); b.await(); t.join(); - } catch(Exception e){ + } catch (Exception e) { unexpectedException(); } } @@ -128,8 +130,8 @@ public class CyclicBarrierTest extends J try { c.await(); threadShouldThrow(); - } catch(InterruptedException success){} - catch(Exception b){ + } catch (InterruptedException success) {} + catch (Exception b) { threadUnexpectedException(); } } @@ -138,9 +140,9 @@ public class CyclicBarrierTest extends J public void run() { try { c.await(); - threadShouldThrow(); - } catch(BrokenBarrierException success){ - } catch(Exception i){ + threadShouldThrow(); + } catch (BrokenBarrierException success) { + } catch (Exception i) { threadUnexpectedException(); } } @@ -150,9 +152,9 @@ public class CyclicBarrierTest extends J t2.start(); Thread.sleep(SHORT_DELAY_MS); t1.interrupt(); - t1.join(); + t1.join(); t2.join(); - } catch(InterruptedException e){ + } catch (InterruptedException e) { unexpectedException(); } } @@ -162,14 +164,14 @@ public class CyclicBarrierTest extends J * throw BrokenBarrierException */ public void testAwait2_Interrupted_BrokenBarrier() { - final CyclicBarrier c = new CyclicBarrier(3); + final CyclicBarrier c = new CyclicBarrier(3); Thread t1 = new Thread(new Runnable() { public void run() { try { c.await(LONG_DELAY_MS, TimeUnit.MILLISECONDS); threadShouldThrow(); - } catch(InterruptedException success){ - } catch(Exception b){ + } catch (InterruptedException success) { + } catch (Exception b) { threadUnexpectedException(); } } @@ -178,9 +180,9 @@ public class CyclicBarrierTest extends J public void run() { try { c.await(LONG_DELAY_MS, TimeUnit.MILLISECONDS); - threadShouldThrow(); - } catch(BrokenBarrierException success){ - } catch(Exception i){ + threadShouldThrow(); + } catch (BrokenBarrierException success) { + } catch (Exception i) { threadUnexpectedException(); } } @@ -190,13 +192,13 @@ public class CyclicBarrierTest extends J t2.start(); Thread.sleep(SHORT_DELAY_MS); t1.interrupt(); - t1.join(); + t1.join(); t2.join(); - } catch(InterruptedException e){ + } catch (InterruptedException e) { unexpectedException(); } } - + /** * A timeout in timed await throws TimeoutException */ @@ -207,17 +209,17 @@ public class CyclicBarrierTest extends J try { c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS); threadShouldThrow(); - } catch(TimeoutException success){ - } catch(Exception b){ + } catch (TimeoutException success) { + } catch (Exception b) { threadUnexpectedException(); - + } } }); try { t.start(); - t.join(); - } catch(InterruptedException e){ + t.join(); + } catch (InterruptedException e) { unexpectedException(); } } @@ -227,14 +229,14 @@ public class CyclicBarrierTest extends J * throw BrokenBarrierException */ public void testAwait4_Timeout_BrokenBarrier() { - final CyclicBarrier c = new CyclicBarrier(3); + final CyclicBarrier c = new CyclicBarrier(3); Thread t1 = new Thread(new Runnable() { public void run() { try { c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS); threadShouldThrow(); - } catch(TimeoutException success){ - } catch(Exception b){ + } catch (TimeoutException success) { + } catch (Exception b) { threadUnexpectedException(); } } @@ -243,9 +245,9 @@ public class CyclicBarrierTest extends J public void run() { try { c.await(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); - threadShouldThrow(); - } catch(BrokenBarrierException success){ - } catch(Exception i){ + threadShouldThrow(); + } catch (BrokenBarrierException success) { + } catch (Exception i) { threadUnexpectedException(); } } @@ -253,9 +255,9 @@ public class CyclicBarrierTest extends J try { t1.start(); t2.start(); - t1.join(); + t1.join(); t2.join(); - } catch(InterruptedException e){ + } catch (InterruptedException e) { unexpectedException(); } } @@ -265,14 +267,14 @@ public class CyclicBarrierTest extends J * throw BrokenBarrierException */ public void testAwait5_Timeout_BrokenBarrier() { - final CyclicBarrier c = new CyclicBarrier(3); + final CyclicBarrier c = new CyclicBarrier(3); Thread t1 = new Thread(new Runnable() { public void run() { try { c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS); threadShouldThrow(); - } catch(TimeoutException success){ - } catch(Exception b){ + } catch (TimeoutException success) { + } catch (Exception b) { threadUnexpectedException(); } } @@ -281,9 +283,9 @@ public class CyclicBarrierTest extends J public void run() { try { c.await(); - threadShouldThrow(); - } catch(BrokenBarrierException success){ - } catch(Exception i){ + threadShouldThrow(); + } catch (BrokenBarrierException success) { + } catch (Exception i) { threadUnexpectedException(); } } @@ -291,13 +293,13 @@ public class CyclicBarrierTest extends J try { t1.start(); t2.start(); - t1.join(); + t1.join(); t2.join(); - } catch(InterruptedException e){ + } catch (InterruptedException e) { unexpectedException(); } } - + /** * A reset of an active barrier causes waiting threads to throw * BrokenBarrierException @@ -309,8 +311,8 @@ public class CyclicBarrierTest extends J try { c.await(); threadShouldThrow(); - } catch(BrokenBarrierException success){} - catch(Exception b){ + } catch (BrokenBarrierException success) {} + catch (Exception b) { threadUnexpectedException(); } } @@ -319,9 +321,9 @@ public class CyclicBarrierTest extends J public void run() { try { c.await(); - threadShouldThrow(); - } catch(BrokenBarrierException success){ - } catch(Exception i){ + threadShouldThrow(); + } catch (BrokenBarrierException success) { + } catch (Exception i) { threadUnexpectedException(); } } @@ -331,9 +333,9 @@ public class CyclicBarrierTest extends J t2.start(); Thread.sleep(SHORT_DELAY_MS); c.reset(); - t1.join(); + t1.join(); t2.join(); - } catch(InterruptedException e){ + } catch (InterruptedException e) { unexpectedException(); } } @@ -348,7 +350,7 @@ public class CyclicBarrierTest extends J public void run() { try { c.await(); - } catch(Exception b){ + } catch (Exception b) { threadUnexpectedException(); } } @@ -357,7 +359,7 @@ public class CyclicBarrierTest extends J public void run() { try { c.await(); - } catch(Exception i){ + } catch (Exception i) { threadUnexpectedException(); } } @@ -367,11 +369,256 @@ public class CyclicBarrierTest extends J t1.start(); t2.start(); c.await(); - t1.join(); + t1.join(); t2.join(); - } catch(Exception e){ + } catch (Exception e) { unexpectedException(); } } + /** + * All threads block while a barrier is broken. + */ + public void testReset_Leakage() { + try { + 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) { + } + } + } + }; + + t.start(); + for ( int i = 0; i < 4; i++) { + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + } + done.set(true); + t.interrupt(); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * Reset of a non-broken barrier does not break barrier + */ + public void testResetWithoutBreakage() { + try { + final CyclicBarrier start = new CyclicBarrier(3); + final CyclicBarrier barrier = new CyclicBarrier(3); + for (int i = 0; i < 3; i++) { + Thread t1 = new Thread(new Runnable() { + public void run() { + try { start.await(); } + catch (Exception ie) { + threadFail("start barrier"); + } + try { barrier.await(); } + catch (Throwable thrown) { + unexpectedException(); + }}}); + + Thread t2 = new Thread(new Runnable() { + public void run() { + try { start.await(); } + catch (Exception ie) { + threadFail("start barrier"); + } + try { barrier.await(); } + catch (Throwable thrown) { + unexpectedException(); + }}}); + + + t1.start(); + t2.start(); + try { start.await(); } + catch (Exception ie) { threadFail("start barrier"); } + barrier.await(); + t1.join(); + t2.join(); + assertFalse(barrier.isBroken()); + assertEquals(0, barrier.getNumberWaiting()); + if (i == 1) barrier.reset(); + assertFalse(barrier.isBroken()); + assertEquals(0, barrier.getNumberWaiting()); + } + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * Reset of a barrier after interruption reinitializes it. + */ + public void testResetAfterInterrupt() { + try { + final CyclicBarrier start = new CyclicBarrier(3); + final CyclicBarrier barrier = new CyclicBarrier(3); + for (int i = 0; i < 2; i++) { + Thread t1 = new Thread(new Runnable() { + public void run() { + try { start.await(); } + catch (Exception ie) { + threadFail("start barrier"); + } + try { barrier.await(); } + catch (InterruptedException ok) {} + catch (Throwable thrown) { + unexpectedException(); + }}}); + + Thread t2 = new Thread(new Runnable() { + public void run() { + try { start.await(); } + catch (Exception ie) { + threadFail("start barrier"); + } + try { barrier.await(); } + catch (BrokenBarrierException ok) {} + catch (Throwable thrown) { + unexpectedException(); + }}}); + + t1.start(); + t2.start(); + try { start.await(); } + catch (Exception ie) { threadFail("start barrier"); } + t1.interrupt(); + t1.join(); + t2.join(); + assertTrue(barrier.isBroken()); + assertEquals(0, barrier.getNumberWaiting()); + barrier.reset(); + assertFalse(barrier.isBroken()); + assertEquals(0, barrier.getNumberWaiting()); + } + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * Reset of a barrier after timeout reinitializes it. + */ + public void testResetAfterTimeout() { + try { + final CyclicBarrier start = new CyclicBarrier(3); + final CyclicBarrier barrier = new CyclicBarrier(3); + for (int i = 0; i < 2; i++) { + Thread t1 = new Thread(new Runnable() { + public void run() { + try { start.await(); } + catch (Exception ie) { + threadFail("start barrier"); + } + try { barrier.await(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); } + catch (TimeoutException ok) {} + catch (Throwable thrown) { + unexpectedException(); + }}}); + + Thread t2 = new Thread(new Runnable() { + public void run() { + try { start.await(); } + catch (Exception ie) { + threadFail("start barrier"); + } + try { barrier.await(); } + catch (BrokenBarrierException ok) {} + catch (Throwable thrown) { + unexpectedException(); + }}}); + + t1.start(); + t2.start(); + try { start.await(); } + catch (Exception ie) { threadFail("start barrier"); } + t1.join(); + t2.join(); + assertTrue(barrier.isBroken()); + assertEquals(0, barrier.getNumberWaiting()); + barrier.reset(); + assertFalse(barrier.isBroken()); + assertEquals(0, barrier.getNumberWaiting()); + } + } + catch (Exception ex) { + unexpectedException(); + } + } + + + /** + * Reset of a barrier after a failed command reinitializes it. + */ + public void testResetAfterCommandException() { + try { + 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++) { + Thread t1 = new Thread(new Runnable() { + public void run() { + try { start.await(); } + catch (Exception ie) { + threadFail("start barrier"); + } + try { barrier.await(); } + catch (BrokenBarrierException ok) {} + catch (Throwable thrown) { + unexpectedException(); + }}}); + + Thread t2 = new Thread(new Runnable() { + public void run() { + try { start.await(); } + catch (Exception ie) { + threadFail("start barrier"); + } + try { barrier.await(); } + catch (BrokenBarrierException ok) {} + catch (Throwable thrown) { + unexpectedException(); + }}}); + + t1.start(); + t2.start(); + try { start.await(); } + catch (Exception ie) { threadFail("start barrier"); } + while (barrier.getNumberWaiting() < 2) { Thread.yield(); } + try { barrier.await(); } + catch (Exception ok) { } + t1.join(); + t2.join(); + assertTrue(barrier.isBroken()); + assertEquals(0, barrier.getNumberWaiting()); + barrier.reset(); + assertFalse(barrier.isBroken()); + assertEquals(0, barrier.getNumberWaiting()); + } + } + catch (Exception ex) { + unexpectedException(); + } + } }