ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/PhaserTest.java
Revision: 1.24
Committed: Mon Nov 29 15:47:29 2010 UTC (13 years, 5 months ago) by dl
Branch: MAIN
Changes since 1.23: +6 -0 lines
Log Message:
improve javadocs; strengthen getPhase spec; streamline waiting

File Contents

# Content
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
5 * Other contributors include John Vint
6 */
7
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
18 public class PhaserTest extends JSR166TestCase {
19
20 public static void main(String[] args) {
21 junit.textui.TestRunner.run(suite());
22 }
23
24 public static Test suite() {
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, int parties, int unarrived) {
42 assertTrue(phaser.isTerminated());
43 assertTrue(phaser.getPhase() < 0);
44 assertEquals(parties, phaser.getRegisteredParties());
45 assertEquals(unarrived, phaser.getUnarrivedParties());
46 assertEquals(parties - unarrived, phaser.getArrivedParties());
47 }
48
49 protected void assertTerminated(Phaser phaser) {
50 assertTerminated(phaser, 0, 0);
51 }
52
53 /**
54 * Empty constructor builds a new Phaser with no parent, no registered
55 * parties and initial phase number of 0
56 */
57 public void testConstructorDefaultValues() {
58 Phaser phaser = new Phaser();
59 assertNull(phaser.getParent());
60 assertEquals(0, phaser.getRegisteredParties());
61 assertEquals(0, phaser.getArrivedParties());
62 assertEquals(0, phaser.getUnarrivedParties());
63 assertEquals(0, phaser.getPhase());
64 }
65
66 /**
67 * Constructing with a negative number of parties throws
68 * IllegalArgumentException
69 */
70 public void testConstructorNegativeParties() {
71 try {
72 new Phaser(-1);
73 shouldThrow();
74 } catch (IllegalArgumentException success) {}
75 }
76
77 /**
78 * Constructing with a negative number of parties throws
79 * IllegalArgumentException
80 */
81 public void testConstructorNegativeParties2() {
82 try {
83 new Phaser(new Phaser(), -1);
84 shouldThrow();
85 } catch (IllegalArgumentException success) {}
86 }
87
88 /**
89 * Constructing with a number of parties > 65535 throws
90 * IllegalArgumentException
91 */
92 public void testConstructorPartiesExceedsLimit() {
93 new Phaser(maxParties);
94 try {
95 new Phaser(maxParties + 1);
96 shouldThrow();
97 } catch (IllegalArgumentException success) {}
98
99 new Phaser(new Phaser(), maxParties);
100 try {
101 new Phaser(new Phaser(), maxParties + 1);
102 shouldThrow();
103 } catch (IllegalArgumentException success) {}
104 }
105
106 /**
107 * The parent provided to the constructor should be returned from
108 * a later call to getParent
109 */
110 public void testConstructor3() {
111 Phaser parent = new Phaser();
112 assertSame(parent, new Phaser(parent).getParent());
113 assertNull(new Phaser(null).getParent());
114 }
115
116 /**
117 * The parent being input into the parameter should equal the original
118 * parent when being returned
119 */
120 public void testConstructor5() {
121 Phaser parent = new Phaser();
122 assertSame(parent, new Phaser(parent, 0).getParent());
123 assertNull(new Phaser(null, 0).getParent());
124 }
125
126 /**
127 * register() will increment the number of unarrived parties by
128 * one and not affect its arrived parties
129 */
130 public void testRegister1() {
131 Phaser phaser = new Phaser();
132 assertState(phaser, 0, 0, 0);
133 assertEquals(0, phaser.register());
134 assertState(phaser, 0, 1, 1);
135 }
136
137 /**
138 * Registering more than 65536 parties causes IllegalStateException
139 */
140 public void testRegister2() {
141 Phaser phaser = new Phaser(0);
142 assertState(phaser, 0, 0, 0);
143 assertEquals(0, phaser.bulkRegister(maxParties - 10));
144 assertState(phaser, 0, maxParties - 10, maxParties - 10);
145 for (int i = 0; i < 10; i++) {
146 assertState(phaser, 0, maxParties - 10 + i, maxParties - 10 + i);
147 assertEquals(0, phaser.register());
148 }
149 assertState(phaser, 0, maxParties, maxParties);
150 try {
151 phaser.register();
152 shouldThrow();
153 } catch (IllegalStateException success) {}
154
155 try {
156 phaser.bulkRegister(Integer.MAX_VALUE);
157 shouldThrow();
158 } catch (IllegalStateException success) {}
159 }
160
161 /**
162 * register() correctly returns the current barrier phase number when
163 * invoked
164 */
165 public void testRegister3() {
166 Phaser phaser = new Phaser();
167 assertEquals(0, phaser.register());
168 assertEquals(0, phaser.arrive());
169 assertEquals(1, phaser.register());
170 assertState(phaser, 1, 2, 2);
171 }
172
173 /**
174 * register causes the next arrive to not increment the phase rather retain
175 * the phase number
176 */
177 public void testRegister4() {
178 Phaser phaser = new Phaser(1);
179 assertEquals(0, phaser.arrive());
180 assertEquals(1, phaser.register());
181 assertEquals(1, phaser.arrive());
182 assertState(phaser, 1, 2, 1);
183 }
184
185 /**
186 * Invoking bulkRegister with a negative parameter throws an
187 * IllegalArgumentException
188 */
189 public void testBulkRegister1() {
190 try {
191 new Phaser().bulkRegister(-1);
192 shouldThrow();
193 } catch (IllegalArgumentException success) {}
194 }
195
196 /**
197 * bulkRegister should correctly record the number of unarrived parties with
198 * the number of parties being registered
199 */
200 public void testBulkRegister2() {
201 Phaser phaser = new Phaser();
202 assertEquals(0, phaser.bulkRegister(20));
203 assertState(phaser, 0, 20, 20);
204 }
205
206 /**
207 * Registering with a number of parties greater than or equal to 1<<16
208 * throws IllegalStateException.
209 */
210 public void testBulkRegister3() {
211 assertEquals(0, new Phaser().bulkRegister((1 << 16) - 1));
212
213 try {
214 new Phaser().bulkRegister(1 << 16);
215 shouldThrow();
216 } catch (IllegalStateException success) {}
217
218 try {
219 new Phaser(2).bulkRegister((1 << 16) - 2);
220 shouldThrow();
221 } catch (IllegalStateException success) {}
222 }
223
224 /**
225 * the phase number increments correctly when tripping the barrier
226 */
227 public void testPhaseIncrement1() {
228 for (int size = 1; size < nine; size++) {
229 final Phaser phaser = new Phaser(size);
230 for (int index = 0; index <= (1 << size); index++) {
231 int phase = phaser.arrive();
232 assertTrue(index % size == 0 ? (index / size) == phase : index - (phase * size) > 0);
233 }
234 }
235 }
236
237 /**
238 * arrive() on a registered phaser increments phase.
239 */
240 public void testArrive1() {
241 Phaser phaser = new Phaser(1);
242 assertState(phaser, 0, 1, 1);
243 assertEquals(0, phaser.arrive());
244 assertState(phaser, 1, 1, 1);
245 }
246
247 /**
248 * arriveAndDeregister does not wait for others to arrive at barrier
249 */
250 public void testArriveAndDeregister() throws InterruptedException {
251 final Phaser phaser = new Phaser(1);
252 for (int i = 0; i < 10; i++) {
253 assertState(phaser, 0, 1, 1);
254 assertEquals(0, phaser.register());
255 assertState(phaser, 0, 2, 2);
256 assertEquals(0, phaser.arriveAndDeregister());
257 assertState(phaser, 0, 1, 1);
258 }
259 assertEquals(0, phaser.arriveAndDeregister());
260 assertTerminated(phaser);
261 assertEquals(1, phaser.getPhase() + Integer.MIN_VALUE);
262 }
263
264 /**
265 * arriveAndDeregister does not wait for others to arrive at barrier
266 */
267 public void testArrive2() throws InterruptedException {
268 final Phaser phaser = new Phaser();
269 assertEquals(0, phaser.register());
270 List<Thread> threads = new ArrayList<Thread>();
271 for (int i = 0; i < 10; i++) {
272 assertEquals(0, phaser.register());
273 threads.add(newStartedThread(new CheckedRunnable() {
274 public void realRun() throws InterruptedException {
275 assertEquals(0, phaser.arriveAndDeregister());
276 }}));
277 }
278
279 for (Thread thread : threads)
280 awaitTermination(thread, LONG_DELAY_MS);
281 assertState(phaser, 0, 1, 1);
282 assertEquals(0, phaser.arrive());
283 assertState(phaser, 1, 1, 1);
284 }
285
286 /**
287 * arrive() returns a negative number if the Phaser is terminated
288 */
289 public void testArrive3() {
290 Phaser phaser = new Phaser(1);
291 phaser.forceTermination();
292 assertTerminated(phaser, 1, 1);
293 assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
294 assertTrue(phaser.arrive() < 0);
295 assertTrue(phaser.register() < 0);
296 assertTrue(phaser.arriveAndDeregister() < 0);
297 assertTrue(phaser.awaitAdvance(1) < 0);
298 assertTrue(phaser.getPhase() < 0);
299 }
300
301 /**
302 * arriveAndDeregister() throws IllegalStateException if number of
303 * registered or unarrived parties would become negative
304 */
305 public void testArriveAndDeregister1() {
306 try {
307 Phaser phaser = new Phaser();
308 phaser.arriveAndDeregister();
309 shouldThrow();
310 } catch (IllegalStateException success) {}
311 }
312
313 /**
314 * arriveAndDeregister reduces the number of arrived parties
315 */
316 public void testArriveAndDeregister2() {
317 final Phaser phaser = new Phaser(1);
318 assertEquals(0, phaser.register());
319 assertEquals(0, phaser.arrive());
320 assertState(phaser, 0, 2, 1);
321 assertEquals(0, phaser.arriveAndDeregister());
322 assertState(phaser, 1, 1, 1);
323 }
324
325 /**
326 * arriveAndDeregister arrives at the barrier on a phaser with a parent and
327 * when a deregistration occurs and causes the phaser to have zero parties
328 * its parent will be deregistered as well
329 */
330 public void testArriveAndDeregister3() {
331 Phaser parent = new Phaser();
332 Phaser child = new Phaser(parent);
333 assertState(child, 0, 0, 0);
334 assertState(parent, 0, 0, 0);
335 assertEquals(0, child.register());
336 assertState(child, 0, 1, 1);
337 assertState(parent, 0, 1, 1);
338 assertEquals(0, child.arriveAndDeregister());
339 assertTerminated(child);
340 assertTerminated(parent);
341 }
342
343 /**
344 * arriveAndDeregister deregisters one party from its parent when
345 * the number of parties of child is zero after deregistration
346 */
347 public void testArriveAndDeregister4() {
348 Phaser parent = new Phaser();
349 Phaser child = new Phaser(parent);
350 assertEquals(0, parent.register());
351 assertEquals(0, child.register());
352 assertState(child, 0, 1, 1);
353 assertState(parent, 0, 2, 2);
354 assertEquals(0, child.arriveAndDeregister());
355 assertState(child, 0, 0, 0);
356 assertState(parent, 0, 1, 1);
357 }
358
359 /**
360 * arriveAndDeregister deregisters one party from its parent when
361 * the number of parties of root is nonzero after deregistration.
362 */
363 public void testArriveAndDeregister5() {
364 Phaser root = new Phaser();
365 Phaser parent = new Phaser(root);
366 Phaser child = new Phaser(parent);
367 assertState(root, 0, 0, 0);
368 assertState(parent, 0, 0, 0);
369 assertState(child, 0, 0, 0);
370 assertEquals(0, child.register());
371 assertState(root, 0, 1, 1);
372 assertState(parent, 0, 1, 1);
373 assertState(child, 0, 1, 1);
374 assertEquals(0, child.arriveAndDeregister());
375 assertTerminated(child);
376 assertTerminated(parent);
377 assertTerminated(root);
378 assertEquals(1, root.getPhase() + Integer.MIN_VALUE);
379 }
380
381 /**
382 * arriveAndDeregister returns the phase in which it leaves the
383 * phaser in after deregistration
384 */
385 public void testArriveAndDeregister6() throws InterruptedException {
386 final Phaser phaser = new Phaser(2);
387 Thread t = newStartedThread(new CheckedRunnable() {
388 public void realRun() {
389 assertEquals(0, phaser.arrive());
390 }});
391 assertEquals(1, phaser.arriveAndAwaitAdvance());
392 assertState(phaser, 1, 2, 2);
393 assertEquals(1, phaser.arriveAndDeregister());
394 assertState(phaser, 1, 1, 1);
395 assertEquals(1, phaser.arriveAndDeregister());
396 assertTerminated(phaser);
397 assertEquals(2, phaser.getPhase() + Integer.MIN_VALUE);
398 awaitTermination(t, SHORT_DELAY_MS);
399 }
400
401 /**
402 * awaitAdvance succeeds upon advance
403 */
404 public void testAwaitAdvance1() {
405 final Phaser phaser = new Phaser(1);
406 assertEquals(0, phaser.arrive());
407 assertEquals(1, phaser.awaitAdvance(0));
408 }
409
410 /**
411 * awaitAdvance with a negative parameter will return without affecting the
412 * phaser
413 */
414 public void testAwaitAdvance2() {
415 Phaser phaser = new Phaser();
416 assertTrue(phaser.awaitAdvance(-1) < 0);
417 assertState(phaser, 0, 0, 0);
418 }
419
420 /**
421 * awaitAdvance continues waiting if interrupted before waiting
422 */
423 public void testAwaitAdvanceAfterInterrupt() throws InterruptedException {
424 final Phaser phaser = new Phaser();
425 assertEquals(0, phaser.register());
426 final CountDownLatch threadStarted = new CountDownLatch(1);
427
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 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() 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() throws InterruptedException {
559 final Phaser phaser = new Phaser(1);
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 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() throws InterruptedException {
590 final Phaser phaser = new Phaser(3);
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 assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
609 for (Thread thread : threads)
610 awaitTermination(thread, SMALL_DELAY_MS);
611 assertTrue(phaser.isTerminated());
612 assertTrue(phaser.getPhase() < 0);
613 assertEquals(3, phaser.getRegisteredParties());
614 }
615
616 /**
617 * arriveAndAwaitAdvance throws IllegalStateException with no
618 * unarrived parties
619 */
620 public void testArriveAndAwaitAdvance1() {
621 try {
622 Phaser phaser = new Phaser();
623 phaser.arriveAndAwaitAdvance();
624 shouldThrow();
625 } catch (IllegalStateException success) {}
626 }
627
628 /**
629 * arriveAndAwaitAdvance waits for all threads to arrive, the
630 * number of arrived parties is the same number that is accounted
631 * for when the main thread awaitsAdvance
632 */
633 public void testArriveAndAwaitAdvance3() throws InterruptedException {
634 final Phaser phaser = new Phaser(1);
635 final int THREADS = 3;
636 final CountDownLatch threadsStarted = new CountDownLatch(THREADS);
637 final List<Thread> threads = new ArrayList<Thread>();
638 for (int i = 0; i < THREADS; i++)
639 threads.add(newStartedThread(new CheckedRunnable() {
640 public void realRun() throws InterruptedException {
641 assertEquals(0, phaser.register());
642 threadsStarted.countDown();
643 assertEquals(1, phaser.arriveAndAwaitAdvance());
644 }}));
645
646 assertTrue(threadsStarted.await(MEDIUM_DELAY_MS, MILLISECONDS));
647 long t0 = System.nanoTime();
648 while (phaser.getArrivedParties() < THREADS)
649 Thread.yield();
650 assertEquals(THREADS, phaser.getArrivedParties());
651 assertTrue(NANOSECONDS.toMillis(System.nanoTime() - t0) < SMALL_DELAY_MS);
652 for (Thread thread : threads)
653 assertTrue(thread.isAlive());
654 assertState(phaser, 0, THREADS + 1, 1);
655 phaser.arriveAndAwaitAdvance();
656 for (Thread thread : threads)
657 awaitTermination(thread, SMALL_DELAY_MS);
658 assertState(phaser, 1, THREADS + 1, THREADS + 1);
659 }
660
661 }