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