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.5 by jsr166, Mon Aug 3 20:33:57 2009 UTC vs.
Revision 1.39 by jsr166, Wed Dec 31 19:05:43 2014 UTC

# Line 1 | Line 1
1   /*
2   * Written by Doug Lea with assistance from members of JCP JSR-166
3   * Expert Group and released to the public domain, as explained at
4 < * http://creativecommons.org/licenses/publicdomain
4 > * http://creativecommons.org/publicdomain/zero/1.0/
5   * Other contributors include John Vint
6   */
7  
8 + import static java.util.concurrent.TimeUnit.MILLISECONDS;
9 +
10   import java.util.ArrayList;
11   import java.util.List;
12 + import java.util.concurrent.CountDownLatch;
13 + import java.util.concurrent.Phaser;
14 + import java.util.concurrent.TimeoutException;
15   import java.util.concurrent.atomic.AtomicInteger;
16 < import java.util.concurrent.*;
16 >
17   import junit.framework.Test;
18   import junit.framework.TestSuite;
19  
# Line 22 | Line 27 | public class PhaserTest extends JSR166Te
27          return new TestSuite(PhaserTest.class);
28      }
29  
30 +    private static final int maxParties = 65535;
31 +
32 +    /** Checks state of unterminated phaser. */
33 +    protected void assertState(Phaser phaser,
34 +                               int phase, int parties, int unarrived) {
35 +        assertEquals(phase, phaser.getPhase());
36 +        assertEquals(parties, phaser.getRegisteredParties());
37 +        assertEquals(unarrived, phaser.getUnarrivedParties());
38 +        assertEquals(parties - unarrived, phaser.getArrivedParties());
39 +        assertFalse(phaser.isTerminated());
40 +    }
41 +
42 +    /** Checks state of terminated phaser. */
43 +    protected void assertTerminated(Phaser phaser, int maxPhase, int parties) {
44 +        assertTrue(phaser.isTerminated());
45 +        int expectedPhase = maxPhase + Integer.MIN_VALUE;
46 +        assertEquals(expectedPhase, phaser.getPhase());
47 +        assertEquals(parties, phaser.getRegisteredParties());
48 +        assertEquals(expectedPhase, phaser.register());
49 +        assertEquals(expectedPhase, phaser.arrive());
50 +        assertEquals(expectedPhase, phaser.arriveAndDeregister());
51 +    }
52 +
53 +    protected void assertTerminated(Phaser phaser, int maxPhase) {
54 +        assertTerminated(phaser, maxPhase, 0);
55 +    }
56 +
57      /**
58       * Empty constructor builds a new Phaser with no parent, no registered
59       * parties and initial phase number of 0
60       */
61 <    public void testConstructor1() {
61 >    public void testConstructorDefaultValues() {
62          Phaser phaser = new Phaser();
63          assertNull(phaser.getParent());
64 +        assertEquals(0, phaser.getRegisteredParties());
65          assertEquals(0, phaser.getArrivedParties());
66 +        assertEquals(0, phaser.getUnarrivedParties());
67          assertEquals(0, phaser.getPhase());
68      }
69  
70      /**
71 <     * A negative party number for the constructor throws illegal argument
72 <     * exception
71 >     * Constructing with a negative number of parties throws
72 >     * IllegalArgumentException
73       */
74 <    public void testConstructor2() {
74 >    public void testConstructorNegativeParties() {
75          try {
76              new Phaser(-1);
77 <            this.shouldThrow();
78 <        } catch (IllegalArgumentException success) {
45 <        }
77 >            shouldThrow();
78 >        } catch (IllegalArgumentException success) {}
79      }
80  
81      /**
82 <     * The parent being input into the constructor should equal the original
83 <     * parent when being returned
82 >     * Constructing with a negative number of parties throws
83 >     * IllegalArgumentException
84       */
85 <    public void testConstructor3() {
86 <        Phaser parent = new Phaser();
87 <        assertEquals(parent, new Phaser(parent).getParent());
85 >    public void testConstructorNegativeParties2() {
86 >        try {
87 >            new Phaser(new Phaser(), -1);
88 >            shouldThrow();
89 >        } catch (IllegalArgumentException success) {}
90      }
91  
92      /**
93 <     * A negative party number for the constructor throws illegal argument
94 <     * exception
93 >     * Constructing with a number of parties > 65535 throws
94 >     * IllegalArgumentException
95       */
96 <    public void testConstructor4() {
96 >    public void testConstructorPartiesExceedsLimit() {
97 >        new Phaser(maxParties);
98          try {
99 <            new Phaser(new Phaser(), -1);
99 >            new Phaser(maxParties + 1);
100              shouldThrow();
101 <        } catch (IllegalArgumentException success) {
102 <        }
101 >        } catch (IllegalArgumentException success) {}
102 >
103 >        new Phaser(new Phaser(), maxParties);
104 >        try {
105 >            new Phaser(new Phaser(), maxParties + 1);
106 >            shouldThrow();
107 >        } catch (IllegalArgumentException success) {}
108 >    }
109 >
110 >    /**
111 >     * The parent provided to the constructor should be returned from
112 >     * a later call to getParent
113 >     */
114 >    public void testConstructor3() {
115 >        Phaser parent = new Phaser();
116 >        assertSame(parent, new Phaser(parent).getParent());
117 >        assertNull(new Phaser(null).getParent());
118      }
119  
120      /**
# Line 72 | Line 123 | public class PhaserTest extends JSR166Te
123       */
124      public void testConstructor5() {
125          Phaser parent = new Phaser();
126 <        assertEquals(parent, new Phaser(parent, 0).getParent());
126 >        assertSame(parent, new Phaser(parent, 0).getParent());
127 >        assertNull(new Phaser(null, 0).getParent());
128      }
129  
130      /**
131 <     * register() will increment the number of unarrived parties by one and not
132 <     * affect its arrived parties
131 >     * register() will increment the number of unarrived parties by
132 >     * one and not affect its arrived parties
133       */
134      public void testRegister1() {
135          Phaser phaser = new Phaser();
136 <        assertEquals(0, phaser.getUnarrivedParties());
137 <        phaser.register();
138 <        assertEquals(1, phaser.getUnarrivedParties());
87 <        assertEquals(0, phaser.getArrivedParties());
136 >        assertState(phaser, 0, 0, 0);
137 >        assertEquals(0, phaser.register());
138 >        assertState(phaser, 0, 1, 1);
139      }
140  
141      /**
# Line 92 | Line 143 | public class PhaserTest extends JSR166Te
143       */
144      public void testRegister2() {
145          Phaser phaser = new Phaser(0);
146 <        int expectedUnnarivedParties = (1 << 16) - 1;
147 <        for (int i = 0; i < expectedUnnarivedParties; i++) {
148 <            phaser.register();
149 <            assertEquals(i + 1, phaser.getUnarrivedParties());
146 >        assertState(phaser, 0, 0, 0);
147 >        assertEquals(0, phaser.bulkRegister(maxParties - 10));
148 >        assertState(phaser, 0, maxParties - 10, maxParties - 10);
149 >        for (int i = 0; i < 10; i++) {
150 >            assertState(phaser, 0, maxParties - 10 + i, maxParties - 10 + i);
151 >            assertEquals(0, phaser.register());
152          }
153 +        assertState(phaser, 0, maxParties, maxParties);
154          try {
155              phaser.register();
156              shouldThrow();
157 <        } catch (IllegalStateException success) {
158 <        }
157 >        } catch (IllegalStateException success) {}
158 >
159 >        try {
160 >            phaser.bulkRegister(Integer.MAX_VALUE);
161 >            shouldThrow();
162 >        } catch (IllegalStateException success) {}
163 >
164 >        assertEquals(0, phaser.bulkRegister(0));
165 >        assertState(phaser, 0, maxParties, maxParties);
166      }
167  
168      /**
169 <     * register() correctly returns the current barrier phase number when
170 <     * invoked
169 >     * register() correctly returns the current barrier phase number
170 >     * when invoked
171       */
172      public void testRegister3() {
173          Phaser phaser = new Phaser();
174          assertEquals(0, phaser.register());
175 <        phaser.arrive();
175 >        assertEquals(0, phaser.arrive());
176          assertEquals(1, phaser.register());
177 +        assertState(phaser, 1, 2, 2);
178      }
179  
180      /**
181 <     * register causes the next arrive to not increment the phase rather retain
182 <     * the phase number
181 >     * register causes the next arrive to not increment the phase
182 >     * rather retain the phase number
183       */
184      public void testRegister4() {
185          Phaser phaser = new Phaser(1);
186 <        phaser.arrive();
187 <        int expectedPhase = phaser.register();
188 <        phaser.arrive();
189 <        assertEquals(expectedPhase, phaser.getPhase());
186 >        assertEquals(0, phaser.arrive());
187 >        assertEquals(1, phaser.register());
188 >        assertEquals(1, phaser.arrive());
189 >        assertState(phaser, 1, 2, 1);
190      }
191  
192 <    public void testRegister5() {
193 <        Phaser phaser = new Phaser();
194 <        phaser.register();
195 <        assertEquals(1, phaser.getUnarrivedParties());
192 >    /**
193 >     * register on a subphaser that is currently empty succeeds, even
194 >     * in the presence of another non-empty subphaser
195 >     */
196 >    public void testRegisterEmptySubPhaser() {
197 >        Phaser root = new Phaser();
198 >        Phaser child1 = new Phaser(root, 1);
199 >        Phaser child2 = new Phaser(root, 0);
200 >        assertEquals(0, child2.register());
201 >        assertState(root, 0, 2, 2);
202 >        assertState(child1, 0, 1, 1);
203 >        assertState(child2, 0, 1, 1);
204 >        assertEquals(0, child2.arriveAndDeregister());
205 >        assertState(root, 0, 1, 1);
206 >        assertState(child1, 0, 1, 1);
207 >        assertState(child2, 0, 0, 0);
208 >        assertEquals(0, child2.register());
209 >        assertEquals(0, child2.arriveAndDeregister());
210 >        assertState(root, 0, 1, 1);
211 >        assertState(child1, 0, 1, 1);
212 >        assertState(child2, 0, 0, 0);
213 >        assertEquals(0, child1.arriveAndDeregister());
214 >        assertTerminated(root, 1);
215 >        assertTerminated(child1, 1);
216 >        assertTerminated(child2, 1);
217      }
218  
219      /**
# Line 141 | Line 224 | public class PhaserTest extends JSR166Te
224          try {
225              new Phaser().bulkRegister(-1);
226              shouldThrow();
227 <        } catch (IllegalArgumentException success) {
145 <        }
227 >        } catch (IllegalArgumentException success) {}
228      }
229  
230      /**
231 <     * bulkRegister should correctly record the number of unarrived parties with
232 <     * the number of parties being registered
231 >     * bulkRegister should correctly record the number of unarrived
232 >     * parties with the number of parties being registered
233       */
234      public void testBulkRegister2() {
235          Phaser phaser = new Phaser();
236 <        phaser.bulkRegister(20);
237 <        assertEquals(20, phaser.getUnarrivedParties());
236 >        assertEquals(0, phaser.bulkRegister(0));
237 >        assertState(phaser, 0, 0, 0);
238 >        assertEquals(0, phaser.bulkRegister(20));
239 >        assertState(phaser, 0, 20, 20);
240      }
241  
242      /**
# Line 160 | Line 244 | public class PhaserTest extends JSR166Te
244       * throws IllegalStateException.
245       */
246      public void testBulkRegister3() {
247 +        assertEquals(0, new Phaser().bulkRegister((1 << 16) - 1));
248 +
249          try {
250              new Phaser().bulkRegister(1 << 16);
251              shouldThrow();
252 <        } catch (IllegalStateException success) {
253 <        }
252 >        } catch (IllegalStateException success) {}
253 >
254 >        try {
255 >            new Phaser(2).bulkRegister((1 << 16) - 2);
256 >            shouldThrow();
257 >        } catch (IllegalStateException success) {}
258      }
259  
260      /**
# Line 181 | Line 271 | public class PhaserTest extends JSR166Te
271      }
272  
273      /**
274 <     *  Arrive() on a registered phaser increments phase.
274 >     * arrive() on a registered phaser increments phase.
275       */
276      public void testArrive1() {
277          Phaser phaser = new Phaser(1);
278 <        phaser.arrive();
279 <        assertEquals(1, phaser.getPhase());
278 >        assertState(phaser, 0, 1, 1);
279 >        assertEquals(0, phaser.arrive());
280 >        assertState(phaser, 1, 1, 1);
281      }
282  
283      /**
284 <     * arrive does not wait for others to arrive at barrier
284 >     * arriveAndDeregister does not wait for others to arrive at barrier
285       */
286 <    public void testArrive2() {
286 >    public void testArriveAndDeregister() {
287          final Phaser phaser = new Phaser(1);
288 <        phaser.register();
289 <        Thread thread = null;
290 <        for (final Runnable r : getRunnables(10, SHORT_DELAY_MS)) {
291 <            phaser.register();
292 <            thread = new Thread(new CheckedRunnable() {
293 <                void realRun() {
203 <                    r.run();
204 <                    phaser.arriveAndDeregister();
205 <                }});
206 <            thread.start();
288 >        for (int i = 0; i < 10; i++) {
289 >            assertState(phaser, 0, 1, 1);
290 >            assertEquals(0, phaser.register());
291 >            assertState(phaser, 0, 2, 2);
292 >            assertEquals(0, phaser.arriveAndDeregister());
293 >            assertState(phaser, 0, 1, 1);
294          }
295 +        assertEquals(0, phaser.arriveAndDeregister());
296 +        assertTerminated(phaser, 1);
297 +    }
298  
299 <        phaser.arrive();
300 <        assertTrue(thread.isAlive());
301 <        assertFalse(phaser.isTerminated());
299 >    /**
300 >     * arriveAndDeregister does not wait for others to arrive at barrier
301 >     */
302 >    public void testArrive2() {
303 >        final Phaser phaser = new Phaser();
304 >        assertEquals(0, phaser.register());
305 >        List<Thread> threads = new ArrayList<Thread>();
306 >        for (int i = 0; i < 10; i++) {
307 >            assertEquals(0, phaser.register());
308 >            threads.add(newStartedThread(new CheckedRunnable() {
309 >                public void realRun() {
310 >                    assertEquals(0, phaser.arriveAndDeregister());
311 >                }}));
312 >        }
313 >
314 >        for (Thread thread : threads)
315 >            awaitTermination(thread);
316 >        assertState(phaser, 0, 1, 1);
317 >        assertEquals(0, phaser.arrive());
318 >        assertState(phaser, 1, 1, 1);
319      }
320  
321      /**
# Line 217 | Line 324 | public class PhaserTest extends JSR166Te
324      public void testArrive3() {
325          Phaser phaser = new Phaser(1);
326          phaser.forceTermination();
327 +        assertTerminated(phaser, 0, 1);
328 +        assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
329          assertTrue(phaser.arrive() < 0);
330 <
330 >        assertTrue(phaser.register() < 0);
331 >        assertTrue(phaser.arriveAndDeregister() < 0);
332 >        assertTrue(phaser.awaitAdvance(1) < 0);
333 >        assertTrue(phaser.getPhase() < 0);
334      }
335  
336      /**
# Line 230 | Line 342 | public class PhaserTest extends JSR166Te
342              Phaser phaser = new Phaser();
343              phaser.arriveAndDeregister();
344              shouldThrow();
345 <
234 <        } catch (IllegalStateException success) {
235 <        }
345 >        } catch (IllegalStateException success) {}
346      }
347  
348      /**
349 <     * arriveAndDeregister deregisters reduces the number of arrived parties
349 >     * arriveAndDeregister reduces the number of arrived parties
350       */
351 <    public void testArriveAndDergeister2() {
351 >    public void testArriveAndDeregister2() {
352          final Phaser phaser = new Phaser(1);
353 <        phaser.register();
354 <        phaser.arrive();
355 <        int p = phaser.getArrivedParties();
356 <        assertTrue(p == 1);
357 <        phaser.arriveAndDeregister();
248 <        assertTrue(phaser.getArrivedParties() < p);
353 >        assertEquals(0, phaser.register());
354 >        assertEquals(0, phaser.arrive());
355 >        assertState(phaser, 0, 2, 1);
356 >        assertEquals(0, phaser.arriveAndDeregister());
357 >        assertState(phaser, 1, 1, 1);
358      }
359  
360      /**
361 <     * arriveAndDeregister arrives to the barrier on a phaser with a parent and
361 >     * arriveAndDeregister arrives at the barrier on a phaser with a parent and
362       * when a deregistration occurs and causes the phaser to have zero parties
363       * its parent will be deregistered as well
364       */
365 <    public void testArriveAndDeregsiter3() {
365 >    public void testArriveAndDeregister3() {
366          Phaser parent = new Phaser();
367 <        Phaser root = new Phaser(parent);
368 <        root.register();
369 <        assertTrue(parent.getUnarrivedParties() > 0);
370 <        assertTrue(root.getUnarrivedParties() > 0);
371 <        root.arriveAndDeregister();
372 <        assertTrue(parent.getUnarrivedParties() == 0);
373 <        assertTrue(root.getUnarrivedParties() == 0);
374 <        assertTrue(root.isTerminated() && parent.isTerminated());
367 >        Phaser child = new Phaser(parent);
368 >        assertState(child, 0, 0, 0);
369 >        assertState(parent, 0, 0, 0);
370 >        assertEquals(0, child.register());
371 >        assertState(child, 0, 1, 1);
372 >        assertState(parent, 0, 1, 1);
373 >        assertEquals(0, child.arriveAndDeregister());
374 >        assertTerminated(child, 1);
375 >        assertTerminated(parent, 1);
376      }
377  
378      /**
379       * arriveAndDeregister deregisters one party from its parent when
380 <     * the number of parties of root is zero after deregistration
380 >     * the number of parties of child is zero after deregistration
381       */
382 <    public void testArriveAndDeregsiter4() {
382 >    public void testArriveAndDeregister4() {
383          Phaser parent = new Phaser();
384 <        Phaser root = new Phaser(parent);
385 <        parent.register();
386 <        root.register();
387 <        int parentParties = parent.getUnarrivedParties();
388 <        root.arriveAndDeregister();
389 <        assertEquals(parentParties - 1, parent.getUnarrivedParties());
384 >        Phaser child = new Phaser(parent);
385 >        assertEquals(0, parent.register());
386 >        assertEquals(0, child.register());
387 >        assertState(child, 0, 1, 1);
388 >        assertState(parent, 0, 2, 2);
389 >        assertEquals(0, child.arriveAndDeregister());
390 >        assertState(child, 0, 0, 0);
391 >        assertState(parent, 0, 1, 1);
392      }
393  
394      /**
# Line 284 | Line 396 | public class PhaserTest extends JSR166Te
396       * the number of parties of root is nonzero after deregistration.
397       */
398      public void testArriveAndDeregister5() {
399 <        Phaser parent = new Phaser();
399 >        Phaser root = new Phaser();
400 >        Phaser parent = new Phaser(root);
401          Phaser child = new Phaser(parent);
402 <        Phaser root = new Phaser(child);
403 <        assertTrue(parent.getUnarrivedParties() > 0);
404 <        assertTrue(child.getUnarrivedParties() > 0);
405 <        root.register();
406 <        root.arriveAndDeregister();
407 <        assertTrue(parent.getUnarrivedParties() == 0);
408 <        assertTrue(child.getUnarrivedParties() == 0);
409 <        assertTrue(root.isTerminated());
402 >        assertState(root, 0, 0, 0);
403 >        assertState(parent, 0, 0, 0);
404 >        assertState(child, 0, 0, 0);
405 >        assertEquals(0, child.register());
406 >        assertState(root, 0, 1, 1);
407 >        assertState(parent, 0, 1, 1);
408 >        assertState(child, 0, 1, 1);
409 >        assertEquals(0, child.arriveAndDeregister());
410 >        assertTerminated(child, 1);
411 >        assertTerminated(parent, 1);
412 >        assertTerminated(root, 1);
413      }
414  
415      /**
# Line 302 | Line 418 | public class PhaserTest extends JSR166Te
418       */
419      public void testArriveAndDeregister6() {
420          final Phaser phaser = new Phaser(2);
421 <        new Thread(new CheckedRunnable() {
422 <            void realRun() {
423 <                getRunnable(SHORT_DELAY_MS).run();
424 <                phaser.arrive();
425 <            }}).start();
426 <        phaser.arriveAndAwaitAdvance();
427 <        int phase = phaser.arriveAndDeregister();
428 <        assertEquals(phase, phaser.getPhase());
421 >        Thread t = newStartedThread(new CheckedRunnable() {
422 >            public void realRun() {
423 >                assertEquals(0, phaser.arrive());
424 >            }});
425 >        assertEquals(1, phaser.arriveAndAwaitAdvance());
426 >        assertState(phaser, 1, 2, 2);
427 >        assertEquals(1, phaser.arriveAndDeregister());
428 >        assertState(phaser, 1, 1, 1);
429 >        assertEquals(1, phaser.arriveAndDeregister());
430 >        assertTerminated(phaser, 2);
431 >        awaitTermination(t);
432      }
433  
434      /**
# Line 317 | Line 436 | public class PhaserTest extends JSR166Te
436       */
437      public void testAwaitAdvance1() {
438          final Phaser phaser = new Phaser(1);
439 <        phaser.awaitAdvance(phaser.arrive());
439 >        assertEquals(0, phaser.arrive());
440 >        assertEquals(1, phaser.awaitAdvance(0));
441      }
442  
443      /**
# Line 325 | Line 445 | public class PhaserTest extends JSR166Te
445       * phaser
446       */
447      public void testAwaitAdvance2() {
448 <        try {
449 <            Phaser phaser = new Phaser();
450 <            phaser.awaitAdvance(-1);
451 <        } catch (Exception failure) {
452 <            this.unexpectedException();
453 <        }
448 >        Phaser phaser = new Phaser();
449 >        assertTrue(phaser.awaitAdvance(-1) < 0);
450 >        assertState(phaser, 0, 0, 0);
451 >    }
452 >
453 >    /**
454 >     * awaitAdvanceInterruptibly blocks interruptibly
455 >     */
456 >    public void testAwaitAdvanceInterruptibly_interruptible() throws InterruptedException {
457 >        final Phaser phaser = new Phaser(1);
458 >        final CountDownLatch pleaseInterrupt = new CountDownLatch(2);
459 >
460 >        Thread t1 = newStartedThread(new CheckedRunnable() {
461 >            public void realRun() {
462 >                Thread.currentThread().interrupt();
463 >                try {
464 >                    phaser.awaitAdvanceInterruptibly(0);
465 >                    shouldThrow();
466 >                } catch (InterruptedException success) {}
467 >                assertFalse(Thread.interrupted());
468 >
469 >                pleaseInterrupt.countDown();
470 >                try {
471 >                    phaser.awaitAdvanceInterruptibly(0);
472 >                    shouldThrow();
473 >                } catch (InterruptedException success) {}
474 >                assertFalse(Thread.interrupted());
475 >            }});
476 >
477 >        Thread t2 = newStartedThread(new CheckedRunnable() {
478 >            public void realRun() throws TimeoutException {
479 >                Thread.currentThread().interrupt();
480 >                try {
481 >                    phaser.awaitAdvanceInterruptibly(0, 2*LONG_DELAY_MS, MILLISECONDS);
482 >                    shouldThrow();
483 >                } catch (InterruptedException success) {}
484 >                assertFalse(Thread.interrupted());
485 >
486 >                pleaseInterrupt.countDown();
487 >                try {
488 >                    phaser.awaitAdvanceInterruptibly(0, 2*LONG_DELAY_MS, MILLISECONDS);
489 >                    shouldThrow();
490 >                } catch (InterruptedException success) {}
491 >                assertFalse(Thread.interrupted());
492 >            }});
493 >
494 >        await(pleaseInterrupt);
495 >        assertState(phaser, 0, 1, 1);
496 >        assertThreadsStayAlive(t1, t2);
497 >        t1.interrupt();
498 >        t2.interrupt();
499 >        awaitTermination(t1);
500 >        awaitTermination(t2);
501 >        assertState(phaser, 0, 1, 1);
502 >        assertEquals(0, phaser.arrive());
503 >        assertState(phaser, 1, 1, 1);
504      }
505  
506      /**
507 <     * awaitAdvance while waiting does not abort on interrupt.
507 >     * awaitAdvance continues waiting if interrupted before waiting
508       */
509 <    public void testAwaitAdvance3() {
509 >    public void testAwaitAdvanceAfterInterrupt() {
510          final Phaser phaser = new Phaser();
511 +        assertEquals(0, phaser.register());
512 +        final CountDownLatch pleaseArrive = new CountDownLatch(1);
513  
514 <        Thread th1 = new Thread(new CheckedRunnable() {
515 <            void realRun() throws InterruptedException {
516 <                phaser.register();
517 <                getRunnable(LONG_DELAY_MS).run();
518 <                phaser.awaitAdvance(phaser.arrive());
514 >        Thread t = newStartedThread(new CheckedRunnable() {
515 >            public void realRun() {
516 >                Thread.currentThread().interrupt();
517 >                assertEquals(0, phaser.register());
518 >                assertEquals(0, phaser.arrive());
519 >                pleaseArrive.countDown();
520 >                assertTrue(Thread.currentThread().isInterrupted());
521 >                assertEquals(1, phaser.awaitAdvance(0));
522 >                assertTrue(Thread.interrupted());
523              }});
524 <        phaser.register();
525 <        th1.start();
526 <        try {
527 <            Thread.sleep(SHORT_DELAY_MS);
528 <            th1.interrupt();
529 <            Thread.sleep(LONG_DELAY_MS);
530 <            phaser.arrive();
531 <        } catch (InterruptedException failure) {
532 <            threadUnexpectedException(failure);
533 <        }
534 <        assertFalse(th1.isInterrupted());
524 >
525 >        await(pleaseArrive);
526 >        waitForThreadToEnterWaitState(t, SHORT_DELAY_MS);
527 >        assertEquals(0, phaser.arrive());
528 >        awaitTermination(t);
529 >
530 >        Thread.currentThread().interrupt();
531 >        assertEquals(1, phaser.awaitAdvance(0));
532 >        assertTrue(Thread.interrupted());
533 >    }
534 >
535 >    /**
536 >     *  awaitAdvance continues waiting if interrupted while waiting
537 >     */
538 >    public void testAwaitAdvanceBeforeInterrupt() {
539 >        final Phaser phaser = new Phaser();
540 >        assertEquals(0, phaser.register());
541 >        final CountDownLatch pleaseArrive = new CountDownLatch(1);
542 >
543 >        Thread t = newStartedThread(new CheckedRunnable() {
544 >            public void realRun() {
545 >                assertEquals(0, phaser.register());
546 >                assertEquals(0, phaser.arrive());
547 >                assertFalse(Thread.currentThread().isInterrupted());
548 >                pleaseArrive.countDown();
549 >                assertEquals(1, phaser.awaitAdvance(0));
550 >                assertTrue(Thread.interrupted());
551 >            }});
552 >
553 >        await(pleaseArrive);
554 >        waitForThreadToEnterWaitState(t, SHORT_DELAY_MS);
555 >        t.interrupt();
556 >        assertEquals(0, phaser.arrive());
557 >        awaitTermination(t);
558 >
559 >        Thread.currentThread().interrupt();
560 >        assertEquals(1, phaser.awaitAdvance(0));
561 >        assertTrue(Thread.interrupted());
562 >    }
563 >
564 >    /**
565 >     * arriveAndAwaitAdvance continues waiting if interrupted before waiting
566 >     */
567 >    public void testArriveAndAwaitAdvanceAfterInterrupt() {
568 >        final Phaser phaser = new Phaser();
569 >        assertEquals(0, phaser.register());
570 >        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
571 >
572 >        Thread t = newStartedThread(new CheckedRunnable() {
573 >            public void realRun() {
574 >                Thread.currentThread().interrupt();
575 >                assertEquals(0, phaser.register());
576 >                pleaseInterrupt.countDown();
577 >                assertTrue(Thread.currentThread().isInterrupted());
578 >                assertEquals(1, phaser.arriveAndAwaitAdvance());
579 >                assertTrue(Thread.currentThread().isInterrupted());
580 >            }});
581 >
582 >        await(pleaseInterrupt);
583 >        waitForThreadToEnterWaitState(t, SHORT_DELAY_MS);
584 >        Thread.currentThread().interrupt();
585 >        assertEquals(1, phaser.arriveAndAwaitAdvance());
586 >        assertTrue(Thread.interrupted());
587 >        awaitTermination(t);
588 >    }
589 >
590 >    /**
591 >     * arriveAndAwaitAdvance continues waiting if interrupted while waiting
592 >     */
593 >    public void testArriveAndAwaitAdvanceBeforeInterrupt() {
594 >        final Phaser phaser = new Phaser();
595 >        assertEquals(0, phaser.register());
596 >        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
597 >
598 >        Thread t = newStartedThread(new CheckedRunnable() {
599 >            public void realRun() {
600 >                assertEquals(0, phaser.register());
601 >                assertFalse(Thread.currentThread().isInterrupted());
602 >                pleaseInterrupt.countDown();
603 >                assertEquals(1, phaser.arriveAndAwaitAdvance());
604 >                assertTrue(Thread.currentThread().isInterrupted());
605 >            }});
606 >
607 >        await(pleaseInterrupt);
608 >        waitForThreadToEnterWaitState(t, SHORT_DELAY_MS);
609 >        t.interrupt();
610 >        Thread.currentThread().interrupt();
611 >        assertEquals(1, phaser.arriveAndAwaitAdvance());
612 >        assertTrue(Thread.interrupted());
613 >        awaitTermination(t);
614      }
615  
616      /**
617       * awaitAdvance atomically waits for all parties within the same phase to
618       * complete before continuing
619       */
620 <    public void testAwaitAdvance4() throws InterruptedException {
620 >    public void testAwaitAdvance4() {
621          final Phaser phaser = new Phaser(4);
622 <        final AtomicInteger phaseCount = new AtomicInteger(0);
622 >        final AtomicInteger count = new AtomicInteger(0);
623          List<Thread> threads = new ArrayList<Thread>();
624 <        for (int i = 0; i < 4; i++) {
625 <            threads.add(new Thread(new CheckedRunnable() {
626 <                void realRun() {
627 <                    int phase = phaser.arrive();
628 <                    phaseCount.incrementAndGet();
629 <                    getRunnable(LONG_DELAY_MS).run();
630 <                    phaser.awaitAdvance(phase);
631 <                    threadAssertTrue(phaseCount.get() == 4);
632 <                }}));
633 <        }
634 <        for (Thread thread : threads)
380 <            thread.start();
624 >        for (int i = 0; i < 4; i++)
625 >            threads.add(newStartedThread(new CheckedRunnable() {
626 >                public void realRun() {
627 >                    for (int k = 0; k < 3; k++) {
628 >                        assertEquals(2*k+1, phaser.arriveAndAwaitAdvance());
629 >                        count.incrementAndGet();
630 >                        assertEquals(2*k+1, phaser.arrive());
631 >                        assertEquals(2*k+2, phaser.awaitAdvance(2*k+1));
632 >                        assertEquals(4*(k+1), count.get());
633 >                    }}}));
634 >
635          for (Thread thread : threads)
636 <            thread.join();
636 >            awaitTermination(thread);
637      }
638  
639      /**
# Line 387 | Line 641 | public class PhaserTest extends JSR166Te
641       */
642      public void testAwaitAdvance5() {
643          final Phaser phaser = new Phaser(1);
644 <        int phase = phaser.awaitAdvance(phaser.arrive());
645 <        assertEquals(phase, phaser.getPhase());
646 <        phaser.register();
647 <        for (int i = 0; i < eight; i++) {
648 <            new Thread(new CheckedRunnable() {
649 <                void realRun() {
650 <                    getRunnable(SHORT_DELAY_MS).run();
644 >        assertEquals(1, phaser.awaitAdvance(phaser.arrive()));
645 >        assertEquals(1, phaser.getPhase());
646 >        assertEquals(1, phaser.register());
647 >        List<Thread> threads = new ArrayList<Thread>();
648 >        for (int i = 0; i < 8; i++) {
649 >            final CountDownLatch latch = new CountDownLatch(1);
650 >            final boolean goesFirst = ((i & 1) == 0);
651 >            threads.add(newStartedThread(new CheckedRunnable() {
652 >                public void realRun() {
653 >                    if (goesFirst)
654 >                        latch.countDown();
655 >                    else
656 >                        await(latch);
657                      phaser.arrive();
658 <                }
659 <                }).start();
660 <            phase = phaser.awaitAdvance(phaser.arrive());
661 <            threadAssertEquals(phase, phaser.getPhase());
658 >                }}));
659 >            if (goesFirst)
660 >                await(latch);
661 >            else
662 >                latch.countDown();
663 >            assertEquals(i + 2, phaser.awaitAdvance(phaser.arrive()));
664 >            assertEquals(i + 2, phaser.getPhase());
665 >        }
666 >        for (Thread thread : threads)
667 >            awaitTermination(thread);
668 >    }
669 >
670 >    /**
671 >     * awaitAdvance returns the current phase in child phasers
672 >     */
673 >    public void testAwaitAdvanceTieredPhaser() throws Exception {
674 >        final Phaser parent = new Phaser();
675 >        final List<Phaser> zeroPartyChildren = new ArrayList<Phaser>(3);
676 >        final List<Phaser> onePartyChildren = new ArrayList<Phaser>(3);
677 >        for (int i = 0; i < 3; i++) {
678 >            zeroPartyChildren.add(new Phaser(parent, 0));
679 >            onePartyChildren.add(new Phaser(parent, 1));
680 >        }
681 >        final List<Phaser> phasers = new ArrayList<Phaser>();
682 >        phasers.addAll(zeroPartyChildren);
683 >        phasers.addAll(onePartyChildren);
684 >        phasers.add(parent);
685 >        for (Phaser phaser : phasers) {
686 >            assertEquals(-42, phaser.awaitAdvance(-42));
687 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42));
688 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, SMALL_DELAY_MS, MILLISECONDS));
689 >        }
690 >
691 >        for (Phaser child : onePartyChildren)
692 >            assertEquals(0, child.arrive());
693 >        for (Phaser phaser : phasers) {
694 >            assertEquals(-42, phaser.awaitAdvance(-42));
695 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42));
696 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, SMALL_DELAY_MS, MILLISECONDS));
697 >            assertEquals(1, phaser.awaitAdvance(0));
698 >            assertEquals(1, phaser.awaitAdvanceInterruptibly(0));
699 >            assertEquals(1, phaser.awaitAdvanceInterruptibly(0, SMALL_DELAY_MS, MILLISECONDS));
700 >        }
701 >
702 >        for (Phaser child : onePartyChildren)
703 >            assertEquals(1, child.arrive());
704 >        for (Phaser phaser : phasers) {
705 >            assertEquals(-42, phaser.awaitAdvance(-42));
706 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42));
707 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, SMALL_DELAY_MS, MILLISECONDS));
708 >            assertEquals(2, phaser.awaitAdvance(0));
709 >            assertEquals(2, phaser.awaitAdvanceInterruptibly(0));
710 >            assertEquals(2, phaser.awaitAdvanceInterruptibly(0, SMALL_DELAY_MS, MILLISECONDS));
711 >            assertEquals(2, phaser.awaitAdvance(1));
712 >            assertEquals(2, phaser.awaitAdvanceInterruptibly(1));
713 >            assertEquals(2, phaser.awaitAdvanceInterruptibly(1, SMALL_DELAY_MS, MILLISECONDS));
714          }
715      }
716  
# Line 407 | Line 719 | public class PhaserTest extends JSR166Te
719       */
720      public void testAwaitAdvance6() {
721          final Phaser phaser = new Phaser(3);
722 <        /*
723 <         * Start new thread. This thread waits a small amount of time
724 <         * and waits for the other two parties to arrive.  The party
725 <         * in the main thread arrives quickly so at best this thread
726 <         * waits for the second thread's party to arrive
727 <         */
728 <        new Thread(new CheckedRunnable() {
729 <            void realRun() {
730 <                getRunnable(SMALL_DELAY_MS).run();
731 <                int phase = phaser.awaitAdvance(phaser.arrive());
732 <                /*
733 <                 * This point is reached when force termination is called in which phase = -1
734 <                 */
735 <                threadAssertTrue(phase < 0);
736 <                threadAssertTrue(phaser.isTerminated());
737 <            }}).start();
426 <        /*
427 <         * This thread will cause the first thread run to wait, in doing so
428 <         * the main thread will force termination in which the first thread
429 <         * should exit peacefully as this one
430 <         */
431 <        new Thread(new CheckedRunnable() {
432 <            void realRun() {
433 <                getRunnable(LONG_DELAY_MS).run();
434 <                int p1 = phaser.arrive();
435 <                int phase = phaser.awaitAdvance(p1);
436 <                threadAssertTrue(phase < 0);
437 <                threadAssertTrue(phaser.isTerminated());
438 <            }}).start();
439 <
440 <        phaser.arrive();
722 >        final CountDownLatch pleaseForceTermination = new CountDownLatch(2);
723 >        final List<Thread> threads = new ArrayList<Thread>();
724 >        for (int i = 0; i < 2; i++) {
725 >            Runnable r = new CheckedRunnable() {
726 >                public void realRun() {
727 >                    assertEquals(0, phaser.arrive());
728 >                    pleaseForceTermination.countDown();
729 >                    assertTrue(phaser.awaitAdvance(0) < 0);
730 >                    assertTrue(phaser.isTerminated());
731 >                    assertTrue(phaser.getPhase() < 0);
732 >                    assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
733 >                    assertEquals(3, phaser.getRegisteredParties());
734 >                }};
735 >            threads.add(newStartedThread(r));
736 >        }
737 >        await(pleaseForceTermination);
738          phaser.forceTermination();
739 +        assertTrue(phaser.isTerminated());
740 +        assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
741 +        for (Thread thread : threads)
742 +            awaitTermination(thread);
743 +        assertEquals(3, phaser.getRegisteredParties());
744      }
745  
746      /**
# Line 450 | Line 752 | public class PhaserTest extends JSR166Te
752              Phaser phaser = new Phaser();
753              phaser.arriveAndAwaitAdvance();
754              shouldThrow();
755 <        } catch (IllegalStateException success) {
454 <        }
455 <    }
456 <
457 <    /**
458 <     * Interrupted arriveAndAwaitAdvance does not throw InterruptedException
459 <     */
460 <    public void testArriveAndAwaitAdvance2() {
461 <        final Phaser phaser = new Phaser(2);
462 <        Thread th = new Thread(new CheckedRunnable() {
463 <            void realRun() {
464 <                phaser.arriveAndAwaitAdvance();
465 <            }});
466 <
467 <        try {
468 <            th.start();
469 <            Thread.sleep(LONG_DELAY_MS);
470 <            th.interrupt();
471 <            Thread.sleep(LONG_DELAY_MS);
472 <            phaser.arrive();
473 <        } catch (InterruptedException failure) {
474 <            this.unexpectedException();
475 <        }
476 <        assertFalse(th.isInterrupted());
755 >        } catch (IllegalStateException success) {}
756      }
757  
758      /**
# Line 483 | Line 762 | public class PhaserTest extends JSR166Te
762       */
763      public void testArriveAndAwaitAdvance3() {
764          final Phaser phaser = new Phaser(1);
765 <        final AtomicInteger arrivingCount = new AtomicInteger(0);
766 <        for (final Runnable run : getRunnables(six, SHORT_DELAY_MS)) {
767 <            new Thread(new CheckedRunnable() {
768 <                void realRun() {
769 <                    phaser.register();
770 <                    run.run();
771 <                    arrivingCount.getAndIncrement();
772 <                    phaser.arrive();
773 <                }}).start();
774 <        }
496 <        int phaseNumber = phaser.arriveAndAwaitAdvance();
497 <        arrivingCount.incrementAndGet();
498 <        //the + 1 adds to expectedArrive to account for the main threads arrival
499 <        int expectedArrived = phaseNumber > 0 ? phaseNumber * six + 1 : phaser.getArrivedParties() + 1;
500 <        threadAssertEquals(expectedArrived, arrivingCount.get());
501 <    }
502 <    // .. initially called, for n tasks via
503 <    private List<Runnable> getRunnables(int size, long wait) {
504 <        List<Runnable> list = new ArrayList<Runnable>();
505 <        for (int i = 0; i < size; i++) {
506 <            list.add(getRunnable(wait));
507 <        }
508 <        return list;
509 <    }
765 >        final int THREADS = 3;
766 >        final CountDownLatch pleaseArrive = new CountDownLatch(THREADS);
767 >        final List<Thread> threads = new ArrayList<Thread>();
768 >        for (int i = 0; i < THREADS; i++)
769 >            threads.add(newStartedThread(new CheckedRunnable() {
770 >                public void realRun() {
771 >                    assertEquals(0, phaser.register());
772 >                    pleaseArrive.countDown();
773 >                    assertEquals(1, phaser.arriveAndAwaitAdvance());
774 >                }}));
775  
776 <    private Runnable getRunnable(final long wait) {
777 <        return new CheckedRunnable() {
778 <            void realRun() {
779 <                try {
780 <                    Thread.sleep(wait);
781 <                } catch (InterruptedException noop) {
782 <                // sleep interruption isn't a problem case for these example
783 <                }
784 <            }
785 <        };
776 >        await(pleaseArrive);
777 >        long startTime = System.nanoTime();
778 >        while (phaser.getArrivedParties() < THREADS)
779 >            Thread.yield();
780 >        assertEquals(THREADS, phaser.getArrivedParties());
781 >        assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
782 >        for (Thread thread : threads)
783 >            waitForThreadToEnterWaitState(thread, SHORT_DELAY_MS);
784 >        for (Thread thread : threads)
785 >            assertTrue(thread.isAlive());
786 >        assertState(phaser, 0, THREADS + 1, 1);
787 >        phaser.arriveAndAwaitAdvance();
788 >        for (Thread thread : threads)
789 >            awaitTermination(thread);
790 >        assertState(phaser, 1, THREADS + 1, THREADS + 1);
791      }
792  
793   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines