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