ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/PhaserTest.java
(Generate patch)

Comparing jsr166/src/test/tck/PhaserTest.java (file contents):
Revision 1.1 by dl, Fri Jul 31 23:02:50 2009 UTC vs.
Revision 1.27 by jsr166, Fri Dec 3 02:09:40 2010 UTC

# Line 8 | Line 8
8   import java.util.ArrayList;
9   import java.util.List;
10   import java.util.concurrent.atomic.AtomicInteger;
11 + import java.util.concurrent.atomic.AtomicBoolean;
12   import java.util.concurrent.*;
13 + import static java.util.concurrent.TimeUnit.MILLISECONDS;
14 + import static java.util.concurrent.TimeUnit.NANOSECONDS;
15   import junit.framework.Test;
16   import junit.framework.TestSuite;
17  
# Line 22 | Line 25 | public class PhaserTest extends JSR166Te
25          return new TestSuite(PhaserTest.class);
26      }
27  
28 +    private static final int maxParties = 65535;
29 +
30 +    /** Checks state of phaser. */
31 +    protected void assertState(Phaser phaser,
32 +                               int phase, int parties, int unarrived) {
33 +        assertEquals(phase, phaser.getPhase());
34 +        assertEquals(parties, phaser.getRegisteredParties());
35 +        assertEquals(unarrived, phaser.getUnarrivedParties());
36 +        assertEquals(parties - unarrived, phaser.getArrivedParties());
37 +        assertTrue((phaser.getPhase() >= 0) ^ phaser.isTerminated());
38 +    }
39 +
40 +    /** Checks state of terminated phaser. */
41 +    protected void assertTerminated(Phaser phaser,
42 +                                    int maxPhase, int parties, int unarrived) {
43 +        assertTrue(phaser.isTerminated());
44 +        int expectedPhase = maxPhase + Integer.MIN_VALUE;
45 +        assertEquals(expectedPhase, phaser.getPhase());
46 +        assertEquals(parties, phaser.getRegisteredParties());
47 +        assertEquals(expectedPhase, phaser.register());
48 +        assertEquals(expectedPhase, phaser.arrive());
49 +        assertEquals(expectedPhase, phaser.arriveAndDeregister());
50 +    }
51 +
52 +    protected void assertTerminated(Phaser phaser, int maxPhase) {
53 +        assertTerminated(phaser, maxPhase, 0, 0);
54 +    }
55 +
56      /**
57       * Empty constructor builds a new Phaser with no parent, no registered
58       * parties and initial phase number of 0
59       */
60 <    public void testConstructor1() {
60 >    public void testConstructorDefaultValues() {
61          Phaser phaser = new Phaser();
62          assertNull(phaser.getParent());
63 +        assertEquals(0, phaser.getRegisteredParties());
64          assertEquals(0, phaser.getArrivedParties());
65 +        assertEquals(0, phaser.getUnarrivedParties());
66          assertEquals(0, phaser.getPhase());
67      }
68  
69      /**
70 <     * A negative party number for the constructor throws illegal argument
71 <     * exception
70 >     * Constructing with a negative number of parties throws
71 >     * IllegalArgumentException
72       */
73 <    public void testConstructor2() {
73 >    public void testConstructorNegativeParties() {
74          try {
75              new Phaser(-1);
76 <            this.shouldThrow();
77 <        } catch (IllegalArgumentException success) {
45 <        }
76 >            shouldThrow();
77 >        } catch (IllegalArgumentException success) {}
78      }
79  
80      /**
81 <     * The parent being input into the constructor should equal the original
82 <     * parent when being returned
81 >     * Constructing with a negative number of parties throws
82 >     * IllegalArgumentException
83       */
84 <    public void testConstructor3() {
85 <        Phaser parent = new Phaser();
86 <        assertEquals(parent, new Phaser(parent).getParent());
84 >    public void testConstructorNegativeParties2() {
85 >        try {
86 >            new Phaser(new Phaser(), -1);
87 >            shouldThrow();
88 >        } catch (IllegalArgumentException success) {}
89      }
90  
91      /**
92 <     * A negative party number for the constructor throws illegal argument
93 <     * exception
92 >     * Constructing with a number of parties > 65535 throws
93 >     * IllegalArgumentException
94       */
95 <    public void testConstructor4() {
95 >    public void testConstructorPartiesExceedsLimit() {
96 >        new Phaser(maxParties);
97          try {
98 <            new Phaser(new Phaser(), -1);
98 >            new Phaser(maxParties + 1);
99              shouldThrow();
100 <        } catch (IllegalArgumentException success) {
101 <        }
100 >        } catch (IllegalArgumentException success) {}
101 >
102 >        new Phaser(new Phaser(), maxParties);
103 >        try {
104 >            new Phaser(new Phaser(), maxParties + 1);
105 >            shouldThrow();
106 >        } catch (IllegalArgumentException success) {}
107 >    }
108 >
109 >    /**
110 >     * The parent provided to the constructor should be returned from
111 >     * a later call to getParent
112 >     */
113 >    public void testConstructor3() {
114 >        Phaser parent = new Phaser();
115 >        assertSame(parent, new Phaser(parent).getParent());
116 >        assertNull(new Phaser(null).getParent());
117      }
118  
119      /**
# Line 72 | Line 122 | public class PhaserTest extends JSR166Te
122       */
123      public void testConstructor5() {
124          Phaser parent = new Phaser();
125 <        assertEquals(parent, new Phaser(parent, 0).getParent());
125 >        assertSame(parent, new Phaser(parent, 0).getParent());
126 >        assertNull(new Phaser(null, 0).getParent());
127      }
128  
129      /**
130 <     * register() will increment the number of unarrived parties by one and not
131 <     * affect its arrived parties
130 >     * register() will increment the number of unarrived parties by
131 >     * one and not affect its arrived parties
132       */
133      public void testRegister1() {
134          Phaser phaser = new Phaser();
135 <        assertEquals(0, phaser.getUnarrivedParties());
136 <        phaser.register();
137 <        assertEquals(1, phaser.getUnarrivedParties());
87 <        assertEquals(0, phaser.getArrivedParties());
135 >        assertState(phaser, 0, 0, 0);
136 >        assertEquals(0, phaser.register());
137 >        assertState(phaser, 0, 1, 1);
138      }
139  
140      /**
141 <     * Registering any more then 65536 parties causes IllegalStateExceptiom
141 >     * Registering more than 65536 parties causes IllegalStateException
142       */
143      public void testRegister2() {
144          Phaser phaser = new Phaser(0);
145 <        int expectedUnnarivedParties = (1 << 16) - 1;
146 <        for (int i = 0; i < expectedUnnarivedParties; i++) {
147 <            phaser.register();
148 <            assertEquals(i + 1, phaser.getUnarrivedParties());
145 >        assertState(phaser, 0, 0, 0);
146 >        assertEquals(0, phaser.bulkRegister(maxParties - 10));
147 >        assertState(phaser, 0, maxParties - 10, maxParties - 10);
148 >        for (int i = 0; i < 10; i++) {
149 >            assertState(phaser, 0, maxParties - 10 + i, maxParties - 10 + i);
150 >            assertEquals(0, phaser.register());
151          }
152 +        assertState(phaser, 0, maxParties, maxParties);
153          try {
154              phaser.register();
155              shouldThrow();
156 <        } catch (IllegalStateException success) {
157 <        } catch (Exception ex) {
158 <            threadUnexpectedException(ex);
159 <        }
156 >        } catch (IllegalStateException success) {}
157 >
158 >        try {
159 >            phaser.bulkRegister(Integer.MAX_VALUE);
160 >            shouldThrow();
161 >        } catch (IllegalStateException success) {}
162      }
163  
164      /**
# Line 113 | Line 168 | public class PhaserTest extends JSR166Te
168      public void testRegister3() {
169          Phaser phaser = new Phaser();
170          assertEquals(0, phaser.register());
171 <        phaser.arrive();
171 >        assertEquals(0, phaser.arrive());
172          assertEquals(1, phaser.register());
173 +        assertState(phaser, 1, 2, 2);
174      }
175  
176      /**
# Line 123 | Line 179 | public class PhaserTest extends JSR166Te
179       */
180      public void testRegister4() {
181          Phaser phaser = new Phaser(1);
182 <        phaser.arrive();
183 <        int expectedPhase = phaser.register();
184 <        phaser.arrive();
185 <        assertEquals(expectedPhase, phaser.getPhase());
130 <    }
131 <
132 <    public void testRegister5() {
133 <        Phaser phaser = new Phaser();
134 <        phaser.register();
135 <        assertEquals(1, phaser.getUnarrivedParties());
182 >        assertEquals(0, phaser.arrive());
183 >        assertEquals(1, phaser.register());
184 >        assertEquals(1, phaser.arrive());
185 >        assertState(phaser, 1, 2, 1);
186      }
187  
188      /**
189       * Invoking bulkRegister with a negative parameter throws an
190 <     * IllegalArgumentExceptiom
190 >     * IllegalArgumentException
191       */
192      public void testBulkRegister1() {
193          try {
194              new Phaser().bulkRegister(-1);
195              shouldThrow();
196 <        } catch (IllegalArgumentException success) {
147 <        }
196 >        } catch (IllegalArgumentException success) {}
197      }
198  
199      /**
# Line 153 | Line 202 | public class PhaserTest extends JSR166Te
202       */
203      public void testBulkRegister2() {
204          Phaser phaser = new Phaser();
205 <        phaser.bulkRegister(20);
206 <        assertEquals(20, phaser.getUnarrivedParties());
205 >        assertEquals(0, phaser.bulkRegister(20));
206 >        assertState(phaser, 0, 20, 20);
207      }
208  
209      /**
210 <     * Registering with a number of parties greater then or equal to 1<<16
211 <     * throws IllegalStateExceptiom.
210 >     * Registering with a number of parties greater than or equal to 1<<16
211 >     * throws IllegalStateException.
212       */
213      public void testBulkRegister3() {
214 +        assertEquals(0, new Phaser().bulkRegister((1 << 16) - 1));
215 +
216          try {
217              new Phaser().bulkRegister(1 << 16);
218              shouldThrow();
219 <        } catch (IllegalStateException success) {
220 <        }
219 >        } catch (IllegalStateException success) {}
220 >
221 >        try {
222 >            new Phaser(2).bulkRegister((1 << 16) - 2);
223 >            shouldThrow();
224 >        } catch (IllegalStateException success) {}
225      }
226  
227      /**
# Line 183 | Line 238 | public class PhaserTest extends JSR166Te
238      }
239  
240      /**
241 <     *  Arrive() on a registered phaser increments phase.
241 >     * arrive() on a registered phaser increments phase.
242       */
243      public void testArrive1() {
244          Phaser phaser = new Phaser(1);
245 <        phaser.arrive();
246 <        assertEquals(1, phaser.getPhase());
245 >        assertState(phaser, 0, 1, 1);
246 >        assertEquals(0, phaser.arrive());
247 >        assertState(phaser, 1, 1, 1);
248      }
249  
250      /**
251 <     * arrive does not wait for others to arrive at barrier
251 >     * arriveAndDeregister does not wait for others to arrive at barrier
252       */
253 <    public void testArrive2() {
253 >    public void testArriveAndDeregister() throws InterruptedException {
254          final Phaser phaser = new Phaser(1);
255 <        phaser.register();
256 <        Thread thread = null;
257 <        for (final Runnable r : getRunnables(10, SHORT_DELAY_MS)) {
258 <            phaser.register();
259 <            thread = new Thread() {
255 >        for (int i = 0; i < 10; i++) {
256 >            assertState(phaser, 0, 1, 1);
257 >            assertEquals(0, phaser.register());
258 >            assertState(phaser, 0, 2, 2);
259 >            assertEquals(0, phaser.arriveAndDeregister());
260 >            assertState(phaser, 0, 1, 1);
261 >        }
262 >        assertEquals(0, phaser.arriveAndDeregister());
263 >        assertTerminated(phaser, 1);
264 >    }
265  
266 <                public void run() {
267 <                    r.run();
268 <                    phaser.arriveAndDeregister();
269 <                }
270 <            };
271 <            thread.start();
266 >    /**
267 >     * arriveAndDeregister does not wait for others to arrive at barrier
268 >     */
269 >    public void testArrive2() throws InterruptedException {
270 >        final Phaser phaser = new Phaser();
271 >        assertEquals(0, phaser.register());
272 >        List<Thread> threads = new ArrayList<Thread>();
273 >        for (int i = 0; i < 10; i++) {
274 >            assertEquals(0, phaser.register());
275 >            threads.add(newStartedThread(new CheckedRunnable() {
276 >                public void realRun() throws InterruptedException {
277 >                    assertEquals(0, phaser.arriveAndDeregister());
278 >                }}));
279          }
280  
281 <        phaser.arrive();
282 <        assertTrue(thread.isAlive());
283 <        assertFalse(phaser.isTerminated());
281 >        for (Thread thread : threads)
282 >            awaitTermination(thread, LONG_DELAY_MS);
283 >        assertState(phaser, 0, 1, 1);
284 >        assertEquals(0, phaser.arrive());
285 >        assertState(phaser, 1, 1, 1);
286      }
287  
288      /**
289 <     * arrive() returns a negative number if the Phaser is termindated
289 >     * arrive() returns a negative number if the Phaser is terminated
290       */
291      public void testArrive3() {
292          Phaser phaser = new Phaser(1);
293          phaser.forceTermination();
294 +        assertTerminated(phaser, 0, 1, 1);
295 +        assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
296          assertTrue(phaser.arrive() < 0);
297 <
297 >        assertTrue(phaser.register() < 0);
298 >        assertTrue(phaser.arriveAndDeregister() < 0);
299 >        assertTrue(phaser.awaitAdvance(1) < 0);
300 >        assertTrue(phaser.getPhase() < 0);
301      }
302  
303      /**
304       * arriveAndDeregister() throws IllegalStateException if number of
305 <     * registered or unnarived parties would become negative
305 >     * registered or unarrived parties would become negative
306       */
307      public void testArriveAndDeregister1() {
308          try {
309              Phaser phaser = new Phaser();
310              phaser.arriveAndDeregister();
311              shouldThrow();
312 <
238 <        } catch (IllegalStateException success) {
239 <        }
312 >        } catch (IllegalStateException success) {}
313      }
314  
315      /**
316 <     * arriveAndDeregister derigisters reduces the number of arrived parties
316 >     * arriveAndDeregister reduces the number of arrived parties
317       */
318 <    public void testArriveAndDergeister2() {
318 >    public void testArriveAndDeregister2() {
319          final Phaser phaser = new Phaser(1);
320 <        phaser.register();
321 <        phaser.arrive();
322 <        int p = phaser.getArrivedParties();
323 <        assertTrue(p == 1);
324 <        phaser.arriveAndDeregister();
252 <        assertTrue(phaser.getArrivedParties() < p);
320 >        assertEquals(0, phaser.register());
321 >        assertEquals(0, phaser.arrive());
322 >        assertState(phaser, 0, 2, 1);
323 >        assertEquals(0, phaser.arriveAndDeregister());
324 >        assertState(phaser, 1, 1, 1);
325      }
326  
327      /**
328 <     * arriveAndDeregister arrives to the barrier on a phaser with a parent and
328 >     * arriveAndDeregister arrives at the barrier on a phaser with a parent and
329       * when a deregistration occurs and causes the phaser to have zero parties
330       * its parent will be deregistered as well
331       */
332 <    public void testArriveAndDeregsiter3() {
332 >    public void testArriveAndDeregister3() {
333          Phaser parent = new Phaser();
334 <        Phaser root = new Phaser(parent);
335 <        root.register();
336 <        assertTrue(parent.getUnarrivedParties() > 0);
337 <        assertTrue(root.getUnarrivedParties() > 0);
338 <        root.arriveAndDeregister();
339 <        assertTrue(parent.getUnarrivedParties() == 0);
340 <        assertTrue(root.getUnarrivedParties() == 0);
341 <        assertTrue(root.isTerminated() && parent.isTerminated());
334 >        Phaser child = new Phaser(parent);
335 >        assertState(child, 0, 0, 0);
336 >        assertState(parent, 0, 0, 0);
337 >        assertEquals(0, child.register());
338 >        assertState(child, 0, 1, 1);
339 >        assertState(parent, 0, 1, 1);
340 >        assertEquals(0, child.arriveAndDeregister());
341 >        assertTerminated(child, 1);
342 >        assertTerminated(parent, 1);
343      }
344  
345      /**
346       * arriveAndDeregister deregisters one party from its parent when
347 <     * the number of parties of root is zero after deregistration
347 >     * the number of parties of child is zero after deregistration
348       */
349 <    public void testArriveAndDeregsiter4() {
349 >    public void testArriveAndDeregister4() {
350          Phaser parent = new Phaser();
351 <        Phaser root = new Phaser(parent);
352 <        parent.register();
353 <        root.register();
354 <        int parentParties = parent.getUnarrivedParties();
355 <        root.arriveAndDeregister();
356 <        assertEquals(parentParties - 1, parent.getUnarrivedParties());
351 >        Phaser child = new Phaser(parent);
352 >        assertEquals(0, parent.register());
353 >        assertEquals(0, child.register());
354 >        assertState(child, 0, 1, 1);
355 >        assertState(parent, 0, 2, 2);
356 >        assertEquals(0, child.arriveAndDeregister());
357 >        assertState(child, 0, 0, 0);
358 >        assertState(parent, 0, 1, 1);
359      }
360  
361      /**
# Line 288 | Line 363 | public class PhaserTest extends JSR166Te
363       * the number of parties of root is nonzero after deregistration.
364       */
365      public void testArriveAndDeregister5() {
366 <        Phaser parent = new Phaser();
366 >        Phaser root = new Phaser();
367 >        Phaser parent = new Phaser(root);
368          Phaser child = new Phaser(parent);
369 <        Phaser root = new Phaser(child);
370 <        assertTrue(parent.getUnarrivedParties() > 0);
371 <        assertTrue(child.getUnarrivedParties() > 0);
372 <        root.register();
373 <        root.arriveAndDeregister();
374 <        assertTrue(parent.getUnarrivedParties() == 0);
375 <        assertTrue(child.getUnarrivedParties() == 0);
376 <        assertTrue(root.isTerminated());
369 >        assertState(root, 0, 0, 0);
370 >        assertState(parent, 0, 0, 0);
371 >        assertState(child, 0, 0, 0);
372 >        assertEquals(0, child.register());
373 >        assertState(root, 0, 1, 1);
374 >        assertState(parent, 0, 1, 1);
375 >        assertState(child, 0, 1, 1);
376 >        assertEquals(0, child.arriveAndDeregister());
377 >        assertTerminated(child, 1);
378 >        assertTerminated(parent, 1);
379 >        assertTerminated(root, 1);
380      }
381  
382      /**
383       * arriveAndDeregister returns the phase in which it leaves the
384       * phaser in after deregistration
385       */
386 <    public void testArriveAndDeregister6() {
386 >    public void testArriveAndDeregister6() throws InterruptedException {
387          final Phaser phaser = new Phaser(2);
388 <        new Thread() {
389 <
390 <            public void run() {
391 <                getRunnable(SHORT_DELAY_MS).run();
392 <                phaser.arrive();
393 <            }
394 <        }.start();
395 <        phaser.arriveAndAwaitAdvance();
396 <        int phase = phaser.arriveAndDeregister();
397 <        assertEquals(phase, phaser.getPhase());
388 >        Thread t = newStartedThread(new CheckedRunnable() {
389 >            public void realRun() {
390 >                assertEquals(0, phaser.arrive());
391 >            }});
392 >        assertEquals(1, phaser.arriveAndAwaitAdvance());
393 >        assertState(phaser, 1, 2, 2);
394 >        assertEquals(1, phaser.arriveAndDeregister());
395 >        assertState(phaser, 1, 1, 1);
396 >        assertEquals(1, phaser.arriveAndDeregister());
397 >        assertTerminated(phaser, 2);
398 >        awaitTermination(t, SHORT_DELAY_MS);
399      }
400  
401      /**
# Line 323 | Line 403 | public class PhaserTest extends JSR166Te
403       */
404      public void testAwaitAdvance1() {
405          final Phaser phaser = new Phaser(1);
406 <        phaser.awaitAdvance(phaser.arrive());
406 >        assertEquals(0, phaser.arrive());
407 >        assertEquals(1, phaser.awaitAdvance(0));
408      }
409  
410      /**
# Line 331 | Line 412 | public class PhaserTest extends JSR166Te
412       * phaser
413       */
414      public void testAwaitAdvance2() {
415 <        try {
416 <            Phaser phaser = new Phaser();
417 <            phaser.awaitAdvance(-1);
337 <        } catch (Exception failure) {
338 <            this.unexpectedException();
339 <        }
415 >        Phaser phaser = new Phaser();
416 >        assertTrue(phaser.awaitAdvance(-1) < 0);
417 >        assertState(phaser, 0, 0, 0);
418      }
419  
420      /**
421 <     * awaitAdvance while waiting does not abort on interrupt.
421 >     * awaitAdvance continues waiting if interrupted before waiting
422       */
423 <    public void testAwaitAdvance3() {
423 >    public void testAwaitAdvanceAfterInterrupt() throws InterruptedException {
424          final Phaser phaser = new Phaser();
425 <        Thread th1 = new Thread() {
425 >        assertEquals(0, phaser.register());
426 >        final CountDownLatch threadStarted = new CountDownLatch(1);
427  
428 <            public void run() {
429 <                try {
430 <                    phaser.register();
431 <                    getRunnable(LONG_DELAY_MS).run();
432 <                    phaser.awaitAdvance(phaser.arrive());
433 <                } catch (Exception failure) {
434 <                    threadUnexpectedException(failure);
435 <                }
428 >        Thread t = newStartedThread(new CheckedRunnable() {
429 >            public void realRun() throws InterruptedException {
430 >                Thread.currentThread().interrupt();
431 >                assertEquals(0, phaser.register());
432 >                assertEquals(0, phaser.arrive());
433 >                threadStarted.countDown();
434 >                assertTrue(Thread.currentThread().isInterrupted());
435 >                assertEquals(1, phaser.awaitAdvance(0));
436 >                assertTrue(Thread.currentThread().isInterrupted());
437 >            }});
438  
439 <            }
440 <        };
441 <        phaser.register();
442 <        th1.start();
443 <        try {
444 <            Thread.sleep(SHORT_DELAY_MS);
445 <            th1.interrupt();
446 <            Thread.sleep(LONG_DELAY_MS);
447 <            phaser.arrive();
448 <        } catch (Exception failure) {
449 <            unexpectedException();
450 <        }
451 <        assertFalse(th1.isInterrupted());
439 >        assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
440 >        waitForThreadToEnterWaitState(t, SMALL_DELAY_MS);
441 >        assertEquals(0, phaser.arrive());
442 >        awaitTermination(t, SMALL_DELAY_MS);
443 >
444 >        Thread.currentThread().interrupt();
445 >        assertEquals(1, phaser.awaitAdvance(0));
446 >        assertTrue(Thread.interrupted());
447 >    }
448 >
449 >    /**
450 >     * awaitAdvance continues waiting if interrupted while waiting
451 >     */
452 >    public void testAwaitAdvanceBeforeInterrupt() throws InterruptedException {
453 >        final Phaser phaser = new Phaser();
454 >        assertEquals(0, phaser.register());
455 >        final CountDownLatch threadStarted = new CountDownLatch(1);
456 >
457 >        Thread t = newStartedThread(new CheckedRunnable() {
458 >            public void realRun() throws InterruptedException {
459 >                assertEquals(0, phaser.register());
460 >                assertEquals(0, phaser.arrive());
461 >                threadStarted.countDown();
462 >                assertFalse(Thread.currentThread().isInterrupted());
463 >                assertEquals(1, phaser.awaitAdvance(0));
464 >                assertTrue(Thread.currentThread().isInterrupted());
465 >            }});
466 >
467 >        assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
468 >        waitForThreadToEnterWaitState(t, SMALL_DELAY_MS);
469 >        t.interrupt();
470 >        assertEquals(0, phaser.arrive());
471 >        awaitTermination(t, SMALL_DELAY_MS);
472 >
473 >        Thread.currentThread().interrupt();
474 >        assertEquals(1, phaser.awaitAdvance(0));
475 >        assertTrue(Thread.interrupted());
476 >    }
477 >
478 >    /**
479 >     * arriveAndAwaitAdvance continues waiting if interrupted before waiting
480 >     */
481 >    public void testArriveAndAwaitAdvanceAfterInterrupt()
482 >            throws InterruptedException {
483 >        final Phaser phaser = new Phaser();
484 >        assertEquals(0, phaser.register());
485 >        final CountDownLatch threadStarted = new CountDownLatch(1);
486 >
487 >        Thread t = newStartedThread(new CheckedRunnable() {
488 >            public void realRun() throws InterruptedException {
489 >                Thread.currentThread().interrupt();
490 >                assertEquals(0, phaser.register());
491 >                threadStarted.countDown();
492 >                assertTrue(Thread.currentThread().isInterrupted());
493 >                assertEquals(1, phaser.arriveAndAwaitAdvance());
494 >                assertTrue(Thread.currentThread().isInterrupted());
495 >            }});
496 >
497 >        assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
498 >        waitForThreadToEnterWaitState(t, SMALL_DELAY_MS);
499 >        Thread.currentThread().interrupt();
500 >        assertEquals(1, phaser.arriveAndAwaitAdvance());
501 >        assertTrue(Thread.interrupted());
502 >        awaitTermination(t, SMALL_DELAY_MS);
503 >    }
504 >
505 >    /**
506 >     * arriveAndAwaitAdvance continues waiting if interrupted while waiting
507 >     */
508 >    public void testArriveAndAwaitAdvanceBeforeInterrupt()
509 >            throws InterruptedException {
510 >        final Phaser phaser = new Phaser();
511 >        assertEquals(0, phaser.register());
512 >        final CountDownLatch threadStarted = new CountDownLatch(1);
513 >
514 >        Thread t = newStartedThread(new CheckedRunnable() {
515 >            public void realRun() throws InterruptedException {
516 >                assertEquals(0, phaser.register());
517 >                threadStarted.countDown();
518 >                assertFalse(Thread.currentThread().isInterrupted());
519 >                assertEquals(1, phaser.arriveAndAwaitAdvance());
520 >                assertTrue(Thread.currentThread().isInterrupted());
521 >            }});
522 >
523 >        assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
524 >        waitForThreadToEnterWaitState(t, SMALL_DELAY_MS);
525 >        t.interrupt();
526 >        Thread.currentThread().interrupt();
527 >        assertEquals(1, phaser.arriveAndAwaitAdvance());
528 >        assertTrue(Thread.interrupted());
529 >        awaitTermination(t, SMALL_DELAY_MS);
530      }
531  
532      /**
533       * awaitAdvance atomically waits for all parties within the same phase to
534       * complete before continuing
535       */
536 <    public void testAwaitAdvance4() {
537 <        final Phaser phaser = new Phaser(four);
538 <        final AtomicInteger phaseCount = new AtomicInteger(0);
539 <        for (int i = 0; i < four; i++) {
540 <            new Thread() {
541 <
542 <                public void run() {
543 <                    int phase = phaser.arrive();
544 <                    phaseCount.incrementAndGet();
545 <                    getRunnable(LONG_DELAY_MS).run();
546 <                    phaser.awaitAdvance(phase);
547 <                    assertTrue(phaseCount.get() == four);
548 <                }
549 <            }.start();
550 <        }
536 >    public void testAwaitAdvance4() throws InterruptedException {
537 >        final Phaser phaser = new Phaser(4);
538 >        final AtomicInteger count = new AtomicInteger(0);
539 >        List<Thread> threads = new ArrayList<Thread>();
540 >        for (int i = 0; i < 4; i++)
541 >            threads.add(newStartedThread(new CheckedRunnable() {
542 >                public void realRun() {
543 >                    for (int k = 0; k < 3; k++) {
544 >                        assertEquals(2*k+1, phaser.arriveAndAwaitAdvance());
545 >                        count.incrementAndGet();
546 >                        assertEquals(2*k+1, phaser.arrive());
547 >                        assertEquals(2*k+2, phaser.awaitAdvance(2*k+1));
548 >                        assertEquals(count.get(), 4*(k+1));
549 >                    }}}));
550 >
551 >        for (Thread thread : threads)
552 >            awaitTermination(thread, MEDIUM_DELAY_MS);
553      }
554  
555      /**
556       * awaitAdvance returns the current phase
557       */
558 <    public void testAwaitAdvance5() {
558 >    public void testAwaitAdvance5() throws InterruptedException {
559          final Phaser phaser = new Phaser(1);
560 <        int phase = phaser.awaitAdvance(phaser.arrive());
561 <        assertEquals(phase, phaser.getPhase());
562 <        phaser.register();
563 <        for (int i = 0; i < eight; i++) {
564 <            new Thread() {
565 <
566 <                public void run() {
567 <                    getRunnable(SHORT_DELAY_MS).run();
560 >        assertEquals(1, phaser.awaitAdvance(phaser.arrive()));
561 >        assertEquals(1, phaser.getPhase());
562 >        assertEquals(1, phaser.register());
563 >        List<Thread> threads = new ArrayList<Thread>();
564 >        for (int i = 0; i < 8; i++) {
565 >            final CountDownLatch latch = new CountDownLatch(1);
566 >            final boolean goesFirst = ((i & 1) == 0);
567 >            threads.add(newStartedThread(new CheckedRunnable() {
568 >                public void realRun() throws InterruptedException {
569 >                    if (goesFirst)
570 >                        latch.countDown();
571 >                    else
572 >                        assertTrue(latch.await(SMALL_DELAY_MS, MILLISECONDS));
573                      phaser.arrive();
574 <                }
575 <            }.start();
576 <            phase = phaser.awaitAdvance(phaser.arrive());
577 <            assertEquals(phase, phaser.getPhase());
574 >                }}));
575 >            if (goesFirst)
576 >                assertTrue(latch.await(SMALL_DELAY_MS, MILLISECONDS));
577 >            else
578 >                latch.countDown();
579 >            assertEquals(i + 2, phaser.awaitAdvance(phaser.arrive()));
580 >            assertEquals(i + 2, phaser.getPhase());
581          }
582 +        for (Thread thread : threads)
583 +            awaitTermination(thread, SMALL_DELAY_MS);
584      }
585  
586      /**
587       * awaitAdvance returns when the phaser is externally terminated
588       */
589 <    public void testAwaitAdvance6() {
589 >    public void testAwaitAdvance6() throws InterruptedException {
590          final Phaser phaser = new Phaser(3);
591 <        /*
592 <         * Start new thread. This thread waits a small amount of time
593 <         * and waits for the other two parties to arrive.  The party
594 <         * in the main thread arrives quickly so at best this thread
595 <         * waits for the second thread's party to arrive
596 <         */
597 <        new Thread() {
598 <            
599 <            public void run() {
600 <                getRunnable(SMALL_DELAY_MS).run();
601 <                int phase = phaser.awaitAdvance(phaser.arrive());
602 <                /*
603 <                 * This point is reached when force termination is called in which phase = -1
604 <                 */
605 <                threadAssertTrue(phase < 0);
606 <                threadAssertTrue(phaser.isTerminated());
436 <            }
437 <        }.start();
438 <        /*
439 <         * This thread will cause the first thread run to wait, in doing so
440 <         * the main thread will force termination in which the first thread
441 <         * should exit peacefully as this one
442 <         */
443 <        new Thread() {
444 <
445 <            public void run() {
446 <                getRunnable(LONG_DELAY_MS).run();
447 <                int p1 = phaser.arrive();
448 <                int phase = phaser.awaitAdvance(p1);
449 <                threadAssertTrue(phase < 0);
450 <                threadAssertTrue(phaser.isTerminated());
451 <            }
452 <        }.start();
453 <
454 <        phaser.arrive();
591 >        final CountDownLatch threadsStarted = new CountDownLatch(2);
592 >        final List<Thread> threads = new ArrayList<Thread>();
593 >        for (int i = 0; i < 2; i++) {
594 >            Runnable r = new CheckedRunnable() {
595 >                public void realRun() {
596 >                    assertEquals(0, phaser.arrive());
597 >                    threadsStarted.countDown();
598 >                    assertTrue(phaser.awaitAdvance(0) < 0);
599 >                    assertTrue(phaser.isTerminated());
600 >                    assertTrue(phaser.getPhase() < 0);
601 >                    assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
602 >                    assertEquals(3, phaser.getRegisteredParties());
603 >                }};
604 >            threads.add(newStartedThread(r));
605 >        }
606 >        threadsStarted.await();
607          phaser.forceTermination();
608 +        assertTrue(phaser.isTerminated());
609 +        assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
610 +        for (Thread thread : threads)
611 +            awaitTermination(thread, SMALL_DELAY_MS);
612 +        assertEquals(3, phaser.getRegisteredParties());
613      }
614  
615      /**
# Line 464 | Line 621 | public class PhaserTest extends JSR166Te
621              Phaser phaser = new Phaser();
622              phaser.arriveAndAwaitAdvance();
623              shouldThrow();
624 <        } catch (IllegalStateException success) {
468 <        }
469 <    }
470 <
471 <    /**
472 <     * Interrupted arriveAndAwaitAdvance does not throw InterruptedException
473 <     */
474 <    public void testArriveAndAwaitAdvance2() {
475 <        final Phaser phaser = new Phaser(2);
476 <        Thread th = new Thread() {
477 <            public void run() {
478 <                try {
479 <                    phaser.arriveAndAwaitAdvance();
480 <                } catch (Exception failure) {
481 <                    threadUnexpectedException(failure);
482 <                }
483 <            }
484 <        };
485 <
486 <        try {
487 <            th.start();
488 <            Thread.sleep(LONG_DELAY_MS);
489 <            th.interrupt();
490 <            Thread.sleep(LONG_DELAY_MS);
491 <            phaser.arrive();
492 <        } catch (InterruptedException failure) {
493 <            this.unexpectedException();
494 <        }
495 <        assertFalse(th.isInterrupted());
624 >        } catch (IllegalStateException success) {}
625      }
626  
627      /**
# Line 500 | Line 629 | public class PhaserTest extends JSR166Te
629       * number of arrived parties is the same number that is accounted
630       * for when the main thread awaitsAdvance
631       */
632 <    public void testArriveAndAwaitAdvance3() {
632 >    public void testArriveAndAwaitAdvance3() throws InterruptedException {
633          final Phaser phaser = new Phaser(1);
634 <        final AtomicInteger arrivingCount = new AtomicInteger(0);
635 <        for (final Runnable run : getRunnables(six, SHORT_DELAY_MS)) {
636 <            new Thread() {
637 <
638 <                public void run() {
639 <                    phaser.register();
640 <                    run.run();
641 <                    arrivingCount.getAndIncrement();
642 <                    phaser.arrive();
643 <                }
644 <            }.start();
645 <        }
646 <        int phaseNumber = phaser.arriveAndAwaitAdvance();
647 <        arrivingCount.incrementAndGet();
648 <        //the + 1 adds to expectedArrive to account for the main threads arrival
649 <        int expectedArrived = phaseNumber > 0 ? phaseNumber * six + 1 : phaser.getArrivedParties() + 1;
650 <        threadAssertEquals(expectedArrived, arrivingCount.get());
651 <    }
652 <    // .. initially called, for n tasks via
653 <    private List<Runnable> getRunnables(int size, long wait) {
654 <        List<Runnable> list = new ArrayList<Runnable>();
655 <        for (int i = 0; i < size; i++) {
656 <            list.add(getRunnable(wait));
657 <        }
529 <        return list;
530 <    }
531 <
532 <    private Runnable getRunnable(final long wait) {
533 <        return new Runnable() {
534 <
535 <            public void run() {
536 <                try {
537 <                    Thread.sleep(wait);
538 <                } catch (InterruptedException noop) {
539 <                // sleep interruption isn't a problem case for these example
540 <                } catch (Exception ex) {
541 <                    threadUnexpectedException(ex);
542 <                }
543 <
544 <            }
545 <        };
634 >        final int THREADS = 3;
635 >        final CountDownLatch threadsStarted = new CountDownLatch(THREADS);
636 >        final List<Thread> threads = new ArrayList<Thread>();
637 >        for (int i = 0; i < THREADS; i++)
638 >            threads.add(newStartedThread(new CheckedRunnable() {
639 >                public void realRun() throws InterruptedException {
640 >                    assertEquals(0, phaser.register());
641 >                    threadsStarted.countDown();
642 >                    assertEquals(1, phaser.arriveAndAwaitAdvance());
643 >                }}));
644 >
645 >        assertTrue(threadsStarted.await(MEDIUM_DELAY_MS, MILLISECONDS));
646 >        long t0 = System.nanoTime();
647 >        while (phaser.getArrivedParties() < THREADS)
648 >            Thread.yield();
649 >        assertEquals(THREADS, phaser.getArrivedParties());
650 >        assertTrue(NANOSECONDS.toMillis(System.nanoTime() - t0) < SMALL_DELAY_MS);
651 >        for (Thread thread : threads)
652 >            assertTrue(thread.isAlive());
653 >        assertState(phaser, 0, THREADS + 1, 1);
654 >        phaser.arriveAndAwaitAdvance();
655 >        for (Thread thread : threads)
656 >            awaitTermination(thread, SMALL_DELAY_MS);
657 >        assertState(phaser, 1, THREADS + 1, THREADS + 1);
658      }
659  
660   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines