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