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