--- jsr166/src/test/tck/PhaserTest.java 2010/10/15 22:43:02 1.19 +++ jsr166/src/test/tck/PhaserTest.java 2017/05/13 23:05:02 1.46 @@ -1,69 +1,77 @@ /* * 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 + * http://creativecommons.org/publicdomain/zero/1.0/ * Other contributors include John Vint */ +import static java.util.concurrent.TimeUnit.MILLISECONDS; + import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Phaser; +import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.*; -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static java.util.concurrent.TimeUnit.NANOSECONDS; + import junit.framework.Test; import junit.framework.TestSuite; public class PhaserTest extends JSR166TestCase { public static void main(String[] args) { - junit.textui.TestRunner.run(suite()); + main(suite(), args); } public static Test suite() { return new TestSuite(PhaserTest.class); } - /** Checks state of phaser. */ + private static final int maxParties = 65535; + + /** Checks state of unterminated phaser. */ protected void assertState(Phaser phaser, int phase, int parties, int unarrived) { assertEquals(phase, phaser.getPhase()); assertEquals(parties, phaser.getRegisteredParties()); assertEquals(unarrived, phaser.getUnarrivedParties()); assertEquals(parties - unarrived, phaser.getArrivedParties()); - assertTrue((phaser.getPhase() >= 0) ^ phaser.isTerminated()); + assertFalse(phaser.isTerminated()); } /** Checks state of terminated phaser. */ - protected void assertTerminated(Phaser phaser, int parties, int unarrived) { + protected void assertTerminated(Phaser phaser, int maxPhase, int parties) { assertTrue(phaser.isTerminated()); - assertTrue(phaser.getPhase() < 0); + int expectedPhase = maxPhase + Integer.MIN_VALUE; + assertEquals(expectedPhase, phaser.getPhase()); assertEquals(parties, phaser.getRegisteredParties()); - assertEquals(unarrived, phaser.getUnarrivedParties()); - assertEquals(parties - unarrived, phaser.getArrivedParties()); + assertEquals(expectedPhase, phaser.register()); + assertEquals(expectedPhase, phaser.arrive()); + assertEquals(expectedPhase, phaser.arriveAndDeregister()); } - protected void assertTerminated(Phaser phaser) { - assertTerminated(phaser, 0, 0); + protected void assertTerminated(Phaser phaser, int maxPhase) { + assertTerminated(phaser, maxPhase, 0); } /** * Empty constructor builds a new Phaser with no parent, no registered * parties and initial phase number of 0 */ - public void testConstructor1() { + public void testConstructorDefaultValues() { Phaser phaser = new Phaser(); assertNull(phaser.getParent()); + assertEquals(0, phaser.getRegisteredParties()); assertEquals(0, phaser.getArrivedParties()); + assertEquals(0, phaser.getUnarrivedParties()); assertEquals(0, phaser.getPhase()); } /** - * A negative party number for the constructor throws illegal argument - * exception + * Constructing with a negative number of parties throws + * IllegalArgumentException */ - public void testConstructor2() { + public void testConstructorNegativeParties() { try { new Phaser(-1); shouldThrow(); @@ -71,37 +79,57 @@ public class PhaserTest extends JSR166Te } /** - * The parent being input into the constructor should equal the original - * parent when being returned + * Constructing with a negative number of parties throws + * IllegalArgumentException */ - public void testConstructor3() { - Phaser parent = new Phaser(); - assertEquals(parent, new Phaser(parent).getParent()); + public void testConstructorNegativeParties2() { + try { + new Phaser(new Phaser(), -1); + shouldThrow(); + } catch (IllegalArgumentException success) {} } /** - * A negative party number for the constructor throws illegal argument - * exception + * Constructing with a number of parties > 65535 throws + * IllegalArgumentException */ - public void testConstructor4() { + public void testConstructorPartiesExceedsLimit() { + new Phaser(maxParties); try { - new Phaser(new Phaser(), -1); + new Phaser(maxParties + 1); + shouldThrow(); + } catch (IllegalArgumentException success) {} + + new Phaser(new Phaser(), maxParties); + try { + new Phaser(new Phaser(), maxParties + 1); shouldThrow(); } catch (IllegalArgumentException success) {} } /** + * The parent provided to the constructor should be returned from + * a later call to getParent + */ + public void testConstructor3() { + Phaser parent = new Phaser(); + assertSame(parent, new Phaser(parent).getParent()); + assertNull(new Phaser(null).getParent()); + } + + /** * The parent being input into the parameter should equal the original * parent when being returned */ public void testConstructor5() { Phaser parent = new Phaser(); - assertEquals(parent, new Phaser(parent, 0).getParent()); + assertSame(parent, new Phaser(parent, 0).getParent()); + assertNull(new Phaser(null, 0).getParent()); } /** - * register() will increment the number of unarrived parties by one and not - * affect its arrived parties + * register() will increment the number of unarrived parties by + * one and not affect its arrived parties */ public void testRegister1() { Phaser phaser = new Phaser(); @@ -115,7 +143,6 @@ public class PhaserTest extends JSR166Te */ public void testRegister2() { Phaser phaser = new Phaser(0); - int maxParties = (1 << 16) - 1; assertState(phaser, 0, 0, 0); assertEquals(0, phaser.bulkRegister(maxParties - 10)); assertState(phaser, 0, maxParties - 10, maxParties - 10); @@ -128,11 +155,19 @@ public class PhaserTest extends JSR166Te phaser.register(); shouldThrow(); } catch (IllegalStateException success) {} + + try { + phaser.bulkRegister(Integer.MAX_VALUE); + shouldThrow(); + } catch (IllegalStateException success) {} + + assertEquals(0, phaser.bulkRegister(0)); + assertState(phaser, 0, maxParties, maxParties); } /** - * register() correctly returns the current barrier phase number when - * invoked + * register() correctly returns the current barrier phase number + * when invoked */ public void testRegister3() { Phaser phaser = new Phaser(); @@ -143,8 +178,8 @@ public class PhaserTest extends JSR166Te } /** - * register causes the next arrive to not increment the phase rather retain - * the phase number + * register causes the next arrive to not increment the phase + * rather retain the phase number */ public void testRegister4() { Phaser phaser = new Phaser(1); @@ -155,6 +190,33 @@ public class PhaserTest extends JSR166Te } /** + * register on a subphaser that is currently empty succeeds, even + * in the presence of another non-empty subphaser + */ + public void testRegisterEmptySubPhaser() { + Phaser root = new Phaser(); + Phaser child1 = new Phaser(root, 1); + Phaser child2 = new Phaser(root, 0); + assertEquals(0, child2.register()); + assertState(root, 0, 2, 2); + assertState(child1, 0, 1, 1); + assertState(child2, 0, 1, 1); + assertEquals(0, child2.arriveAndDeregister()); + assertState(root, 0, 1, 1); + assertState(child1, 0, 1, 1); + assertState(child2, 0, 0, 0); + assertEquals(0, child2.register()); + assertEquals(0, child2.arriveAndDeregister()); + assertState(root, 0, 1, 1); + assertState(child1, 0, 1, 1); + assertState(child2, 0, 0, 0); + assertEquals(0, child1.arriveAndDeregister()); + assertTerminated(root, 1); + assertTerminated(child1, 1); + assertTerminated(child2, 1); + } + + /** * Invoking bulkRegister with a negative parameter throws an * IllegalArgumentException */ @@ -166,11 +228,13 @@ public class PhaserTest extends JSR166Te } /** - * bulkRegister should correctly record the number of unarrived parties with - * the number of parties being registered + * bulkRegister should correctly record the number of unarrived + * parties with the number of parties being registered */ public void testBulkRegister2() { Phaser phaser = new Phaser(); + assertEquals(0, phaser.bulkRegister(0)); + assertState(phaser, 0, 0, 0); assertEquals(0, phaser.bulkRegister(20)); assertState(phaser, 0, 20, 20); } @@ -219,7 +283,7 @@ public class PhaserTest extends JSR166Te /** * arriveAndDeregister does not wait for others to arrive at barrier */ - public void testArriveAndDeregister() throws InterruptedException { + public void testArriveAndDeregister() { final Phaser phaser = new Phaser(1); for (int i = 0; i < 10; i++) { assertState(phaser, 0, 1, 1); @@ -229,26 +293,26 @@ public class PhaserTest extends JSR166Te assertState(phaser, 0, 1, 1); } assertEquals(0, phaser.arriveAndDeregister()); - assertTerminated(phaser); + assertTerminated(phaser, 1); } /** * arriveAndDeregister does not wait for others to arrive at barrier */ - public void testArrive2() throws InterruptedException { + public void testArrive2() { final Phaser phaser = new Phaser(); assertEquals(0, phaser.register()); - List threads = new ArrayList(); + List threads = new ArrayList<>(); for (int i = 0; i < 10; i++) { assertEquals(0, phaser.register()); threads.add(newStartedThread(new CheckedRunnable() { - public void realRun() throws InterruptedException { + public void realRun() { assertEquals(0, phaser.arriveAndDeregister()); }})); } for (Thread thread : threads) - awaitTermination(thread, LONG_DELAY_MS); + awaitTermination(thread); assertState(phaser, 0, 1, 1); assertEquals(0, phaser.arrive()); assertState(phaser, 1, 1, 1); @@ -260,7 +324,8 @@ public class PhaserTest extends JSR166Te public void testArrive3() { Phaser phaser = new Phaser(1); phaser.forceTermination(); - assertTerminated(phaser, 1, 1); + assertTerminated(phaser, 0, 1); + assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE); assertTrue(phaser.arrive() < 0); assertTrue(phaser.register() < 0); assertTrue(phaser.arriveAndDeregister() < 0); @@ -273,8 +338,8 @@ public class PhaserTest extends JSR166Te * registered or unarrived parties would become negative */ public void testArriveAndDeregister1() { + Phaser phaser = new Phaser(); try { - Phaser phaser = new Phaser(); phaser.arriveAndDeregister(); shouldThrow(); } catch (IllegalStateException success) {} @@ -301,13 +366,13 @@ public class PhaserTest extends JSR166Te Phaser parent = new Phaser(); Phaser child = new Phaser(parent); assertState(child, 0, 0, 0); - assertState(parent, 0, 1, 1); + assertState(parent, 0, 0, 0); assertEquals(0, child.register()); assertState(child, 0, 1, 1); assertState(parent, 0, 1, 1); assertEquals(0, child.arriveAndDeregister()); - assertTerminated(child); - assertTerminated(parent); + assertTerminated(child, 1); + assertTerminated(parent, 1); } /** @@ -334,24 +399,24 @@ public class PhaserTest extends JSR166Te Phaser root = new Phaser(); Phaser parent = new Phaser(root); Phaser child = new Phaser(parent); - assertState(root, 0, 1, 1); - assertState(parent, 0, 1, 1); + assertState(root, 0, 0, 0); + assertState(parent, 0, 0, 0); assertState(child, 0, 0, 0); assertEquals(0, child.register()); assertState(root, 0, 1, 1); assertState(parent, 0, 1, 1); assertState(child, 0, 1, 1); assertEquals(0, child.arriveAndDeregister()); - assertTerminated(child); - assertTerminated(parent); - assertTerminated(root); + assertTerminated(child, 1); + assertTerminated(parent, 1); + assertTerminated(root, 1); } /** * arriveAndDeregister returns the phase in which it leaves the * phaser in after deregistration */ - public void testArriveAndDeregister6() throws InterruptedException { + public void testArriveAndDeregister6() { final Phaser phaser = new Phaser(2); Thread t = newStartedThread(new CheckedRunnable() { public void realRun() { @@ -362,8 +427,8 @@ public class PhaserTest extends JSR166Te assertEquals(1, phaser.arriveAndDeregister()); assertState(phaser, 1, 1, 1); assertEquals(1, phaser.arriveAndDeregister()); - assertTerminated(phaser); - awaitTermination(t, SHORT_DELAY_MS); + assertTerminated(phaser, 2); + awaitTermination(t); } /** @@ -386,105 +451,295 @@ public class PhaserTest extends JSR166Te } /** - * awaitAdvance continues waiting if interrupted + * awaitAdvanceInterruptibly blocks interruptibly + */ + public void testAwaitAdvanceInterruptibly_interruptible() throws InterruptedException { + final Phaser phaser = new Phaser(1); + final CountDownLatch pleaseInterrupt = new CountDownLatch(2); + + Thread t1 = newStartedThread(new CheckedRunnable() { + public void realRun() { + Thread.currentThread().interrupt(); + try { + phaser.awaitAdvanceInterruptibly(0); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + pleaseInterrupt.countDown(); + try { + phaser.awaitAdvanceInterruptibly(0); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + }}); + + Thread t2 = newStartedThread(new CheckedRunnable() { + public void realRun() throws TimeoutException { + Thread.currentThread().interrupt(); + try { + phaser.awaitAdvanceInterruptibly(0, 2*LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + pleaseInterrupt.countDown(); + try { + phaser.awaitAdvanceInterruptibly(0, 2*LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + }}); + + await(pleaseInterrupt); + assertState(phaser, 0, 1, 1); + assertThreadsStayAlive(t1, t2); + t1.interrupt(); + t2.interrupt(); + awaitTermination(t1); + awaitTermination(t2); + assertState(phaser, 0, 1, 1); + assertEquals(0, phaser.arrive()); + assertState(phaser, 1, 1, 1); + } + + /** + * awaitAdvance continues waiting if interrupted before waiting */ - public void testAwaitAdvance3() throws InterruptedException { + public void testAwaitAdvanceAfterInterrupt() { final Phaser phaser = new Phaser(); assertEquals(0, phaser.register()); - final CountDownLatch threadStarted = new CountDownLatch(1); + final CountDownLatch pleaseArrive = new CountDownLatch(1); Thread t = newStartedThread(new CheckedRunnable() { - public void realRun() throws InterruptedException { + public void realRun() { + Thread.currentThread().interrupt(); assertEquals(0, phaser.register()); - threadStarted.countDown(); - assertEquals(1, phaser.awaitAdvance(phaser.arrive())); + assertEquals(0, phaser.arrive()); + pleaseArrive.countDown(); assertTrue(Thread.currentThread().isInterrupted()); + assertEquals(1, phaser.awaitAdvance(0)); + assertTrue(Thread.interrupted()); + }}); + + await(pleaseArrive); + assertThreadBlocks(t, Thread.State.WAITING); + assertEquals(0, phaser.arrive()); + awaitTermination(t); + + Thread.currentThread().interrupt(); + assertEquals(1, phaser.awaitAdvance(0)); + assertTrue(Thread.interrupted()); + } + + /** + * awaitAdvance continues waiting if interrupted while waiting + */ + public void testAwaitAdvanceBeforeInterrupt() { + final Phaser phaser = new Phaser(); + assertEquals(0, phaser.register()); + final CountDownLatch pleaseArrive = new CountDownLatch(1); + + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() { + assertEquals(0, phaser.register()); + assertEquals(0, phaser.arrive()); + assertFalse(Thread.currentThread().isInterrupted()); + pleaseArrive.countDown(); + assertEquals(1, phaser.awaitAdvance(0)); + assertTrue(Thread.interrupted()); }}); - assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS)); + + await(pleaseArrive); + assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); assertEquals(0, phaser.arrive()); - awaitTermination(t, SMALL_DELAY_MS); + awaitTermination(t); + + Thread.currentThread().interrupt(); + assertEquals(1, phaser.awaitAdvance(0)); + assertTrue(Thread.interrupted()); + } + + /** + * arriveAndAwaitAdvance continues waiting if interrupted before waiting + */ + public void testArriveAndAwaitAdvanceAfterInterrupt() { + final Phaser phaser = new Phaser(); + assertEquals(0, phaser.register()); + final CountDownLatch pleaseArrive = new CountDownLatch(1); + + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() { + Thread.currentThread().interrupt(); + assertEquals(0, phaser.register()); + pleaseArrive.countDown(); + assertTrue(Thread.currentThread().isInterrupted()); + assertEquals(1, phaser.arriveAndAwaitAdvance()); + assertTrue(Thread.interrupted()); + }}); + + await(pleaseArrive); + assertThreadBlocks(t, Thread.State.WAITING); + Thread.currentThread().interrupt(); + assertEquals(1, phaser.arriveAndAwaitAdvance()); + assertTrue(Thread.interrupted()); + awaitTermination(t); + } + + /** + * arriveAndAwaitAdvance continues waiting if interrupted while waiting + */ + public void testArriveAndAwaitAdvanceBeforeInterrupt() { + final Phaser phaser = new Phaser(); + assertEquals(0, phaser.register()); + final CountDownLatch pleaseInterrupt = new CountDownLatch(1); + + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() { + assertEquals(0, phaser.register()); + assertFalse(Thread.currentThread().isInterrupted()); + pleaseInterrupt.countDown(); + assertEquals(1, phaser.arriveAndAwaitAdvance()); + assertTrue(Thread.interrupted()); + }}); + + await(pleaseInterrupt); + assertThreadBlocks(t, Thread.State.WAITING); + t.interrupt(); + Thread.currentThread().interrupt(); + assertEquals(1, phaser.arriveAndAwaitAdvance()); + assertTrue(Thread.interrupted()); + awaitTermination(t); } /** * awaitAdvance atomically waits for all parties within the same phase to * complete before continuing */ - public void testAwaitAdvance4() throws InterruptedException { + public void testAwaitAdvance4() { final Phaser phaser = new Phaser(4); final AtomicInteger count = new AtomicInteger(0); - List threads = new ArrayList(); + List threads = new ArrayList<>(); for (int i = 0; i < 4; i++) threads.add(newStartedThread(new CheckedRunnable() { public void realRun() { for (int k = 0; k < 3; k++) { - assertEquals(2*k+1, phaser.arriveAndAwaitAdvance()); + assertEquals(2 * k + 1, phaser.arriveAndAwaitAdvance()); count.incrementAndGet(); - assertEquals(2*k+1, phaser.arrive()); - assertEquals(2*k+2, phaser.awaitAdvance(2*k+1)); - assertEquals(count.get(), 4*(k+1)); + assertEquals(2 * k + 1, phaser.arrive()); + assertEquals(2 * k + 2, phaser.awaitAdvance(2 * k + 1)); + assertEquals(4 * (k + 1), count.get()); }}})); for (Thread thread : threads) - awaitTermination(thread, MEDIUM_DELAY_MS); + awaitTermination(thread); } /** * awaitAdvance returns the current phase */ - public void testAwaitAdvance5() throws InterruptedException { + public void testAwaitAdvance5() { final Phaser phaser = new Phaser(1); assertEquals(1, phaser.awaitAdvance(phaser.arrive())); assertEquals(1, phaser.getPhase()); assertEquals(1, phaser.register()); - List threads = new ArrayList(); + List threads = new ArrayList<>(); for (int i = 0; i < 8; i++) { final CountDownLatch latch = new CountDownLatch(1); final boolean goesFirst = ((i & 1) == 0); threads.add(newStartedThread(new CheckedRunnable() { - public void realRun() throws InterruptedException { + public void realRun() { if (goesFirst) latch.countDown(); else - assertTrue(latch.await(SMALL_DELAY_MS, MILLISECONDS)); + await(latch); phaser.arrive(); }})); if (goesFirst) - assertTrue(latch.await(SMALL_DELAY_MS, MILLISECONDS)); + await(latch); else latch.countDown(); assertEquals(i + 2, phaser.awaitAdvance(phaser.arrive())); assertEquals(i + 2, phaser.getPhase()); } for (Thread thread : threads) - awaitTermination(thread, SMALL_DELAY_MS); + awaitTermination(thread); + } + + /** + * awaitAdvance returns the current phase in child phasers + */ + public void testAwaitAdvanceTieredPhaser() throws Exception { + final Phaser parent = new Phaser(); + final List zeroPartyChildren = new ArrayList<>(3); + final List onePartyChildren = new ArrayList<>(3); + for (int i = 0; i < 3; i++) { + zeroPartyChildren.add(new Phaser(parent, 0)); + onePartyChildren.add(new Phaser(parent, 1)); + } + final List phasers = new ArrayList<>(); + phasers.addAll(zeroPartyChildren); + phasers.addAll(onePartyChildren); + phasers.add(parent); + for (Phaser phaser : phasers) { + assertEquals(-42, phaser.awaitAdvance(-42)); + assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42)); + assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, MEDIUM_DELAY_MS, MILLISECONDS)); + } + + for (Phaser child : onePartyChildren) + assertEquals(0, child.arrive()); + for (Phaser phaser : phasers) { + assertEquals(-42, phaser.awaitAdvance(-42)); + assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42)); + assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, MEDIUM_DELAY_MS, MILLISECONDS)); + assertEquals(1, phaser.awaitAdvance(0)); + assertEquals(1, phaser.awaitAdvanceInterruptibly(0)); + assertEquals(1, phaser.awaitAdvanceInterruptibly(0, MEDIUM_DELAY_MS, MILLISECONDS)); + } + + for (Phaser child : onePartyChildren) + assertEquals(1, child.arrive()); + for (Phaser phaser : phasers) { + assertEquals(-42, phaser.awaitAdvance(-42)); + assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42)); + assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, MEDIUM_DELAY_MS, MILLISECONDS)); + assertEquals(2, phaser.awaitAdvance(0)); + assertEquals(2, phaser.awaitAdvanceInterruptibly(0)); + assertEquals(2, phaser.awaitAdvanceInterruptibly(0, MEDIUM_DELAY_MS, MILLISECONDS)); + assertEquals(2, phaser.awaitAdvance(1)); + assertEquals(2, phaser.awaitAdvanceInterruptibly(1)); + assertEquals(2, phaser.awaitAdvanceInterruptibly(1, MEDIUM_DELAY_MS, MILLISECONDS)); + } } /** * awaitAdvance returns when the phaser is externally terminated */ - public void testAwaitAdvance6() throws InterruptedException { + public void testAwaitAdvance6() { final Phaser phaser = new Phaser(3); - final CountDownLatch threadsStarted = new CountDownLatch(2); - final List threads = new ArrayList(); + final CountDownLatch pleaseForceTermination = new CountDownLatch(2); + final List threads = new ArrayList<>(); for (int i = 0; i < 2; i++) { Runnable r = new CheckedRunnable() { public void realRun() { assertEquals(0, phaser.arrive()); - threadsStarted.countDown(); + pleaseForceTermination.countDown(); assertTrue(phaser.awaitAdvance(0) < 0); assertTrue(phaser.isTerminated()); assertTrue(phaser.getPhase() < 0); + assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE); assertEquals(3, phaser.getRegisteredParties()); }}; threads.add(newStartedThread(r)); } - threadsStarted.await(); + await(pleaseForceTermination); phaser.forceTermination(); - for (Thread thread : threads) - awaitTermination(thread, SMALL_DELAY_MS); assertTrue(phaser.isTerminated()); - assertTrue(phaser.getPhase() < 0); + assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE); + for (Thread thread : threads) + awaitTermination(thread); assertEquals(3, phaser.getRegisteredParties()); } @@ -493,72 +748,45 @@ public class PhaserTest extends JSR166Te * unarrived parties */ public void testArriveAndAwaitAdvance1() { + Phaser phaser = new Phaser(); try { - Phaser phaser = new Phaser(); phaser.arriveAndAwaitAdvance(); shouldThrow(); } catch (IllegalStateException success) {} } /** - * Interrupted arriveAndAwaitAdvance does not throw InterruptedException - */ - public void testArriveAndAwaitAdvance2() throws InterruptedException { - final Phaser phaser = new Phaser(2); - final CountDownLatch threadStarted = new CountDownLatch(1); - final AtomicBoolean advanced = new AtomicBoolean(false); - final AtomicBoolean checkedInterruptStatus = new AtomicBoolean(false); - Thread t = newStartedThread(new CheckedRunnable() { - public void realRun() throws InterruptedException { - threadStarted.countDown(); - assertEquals(1, phaser.arriveAndAwaitAdvance()); - assertState(phaser, 1, 2, 2); - advanced.set(true); - assertTrue(Thread.currentThread().isInterrupted()); - while (!checkedInterruptStatus.get()) - Thread.yield(); - }}); - - assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS)); - t.interrupt(); - assertEquals(0, phaser.arrive()); - while (!advanced.get()) - Thread.yield(); - assertTrue(t.isInterrupted()); - checkedInterruptStatus.set(true); - awaitTermination(t, SMALL_DELAY_MS); - } - - /** * arriveAndAwaitAdvance waits for all threads to arrive, the * number of arrived parties is the same number that is accounted * for when the main thread awaitsAdvance */ - public void testArriveAndAwaitAdvance3() throws InterruptedException { + public void testArriveAndAwaitAdvance3() { final Phaser phaser = new Phaser(1); final int THREADS = 3; - final CountDownLatch threadsStarted = new CountDownLatch(THREADS); - final List threads = new ArrayList(); + final CountDownLatch pleaseArrive = new CountDownLatch(THREADS); + final List threads = new ArrayList<>(); for (int i = 0; i < THREADS; i++) threads.add(newStartedThread(new CheckedRunnable() { - public void realRun() throws InterruptedException { + public void realRun() { assertEquals(0, phaser.register()); - threadsStarted.countDown(); + pleaseArrive.countDown(); assertEquals(1, phaser.arriveAndAwaitAdvance()); }})); - assertTrue(threadsStarted.await(MEDIUM_DELAY_MS, MILLISECONDS)); - long t0 = System.nanoTime(); + await(pleaseArrive); + long startTime = System.nanoTime(); while (phaser.getArrivedParties() < THREADS) Thread.yield(); assertEquals(THREADS, phaser.getArrivedParties()); - assertTrue(NANOSECONDS.toMillis(System.nanoTime() - t0) < SMALL_DELAY_MS); + assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); + for (Thread thread : threads) + assertThreadBlocks(thread, Thread.State.WAITING); for (Thread thread : threads) assertTrue(thread.isAlive()); assertState(phaser, 0, THREADS + 1, 1); phaser.arriveAndAwaitAdvance(); for (Thread thread : threads) - awaitTermination(thread, SMALL_DELAY_MS); + awaitTermination(thread); assertState(phaser, 1, THREADS + 1, THREADS + 1); }