ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/PhaserTest.java
Revision: 1.23
Committed: Sat Nov 27 16:47:05 2010 UTC (13 years, 5 months ago) by dl
Branch: MAIN
Changes since 1.22: +3 -3 lines
Log Message:
Remove constraints on tiered deregistration

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 }
262
263 /**
264 * arriveAndDeregister does not wait for others to arrive at barrier
265 */
266 public void testArrive2() throws InterruptedException {
267 final Phaser phaser = new Phaser();
268 assertEquals(0, phaser.register());
269 List<Thread> threads = new ArrayList<Thread>();
270 for (int i = 0; i < 10; i++) {
271 assertEquals(0, phaser.register());
272 threads.add(newStartedThread(new CheckedRunnable() {
273 public void realRun() throws InterruptedException {
274 assertEquals(0, phaser.arriveAndDeregister());
275 }}));
276 }
277
278 for (Thread thread : threads)
279 awaitTermination(thread, LONG_DELAY_MS);
280 assertState(phaser, 0, 1, 1);
281 assertEquals(0, phaser.arrive());
282 assertState(phaser, 1, 1, 1);
283 }
284
285 /**
286 * arrive() returns a negative number if the Phaser is terminated
287 */
288 public void testArrive3() {
289 Phaser phaser = new Phaser(1);
290 phaser.forceTermination();
291 assertTerminated(phaser, 1, 1);
292 assertTrue(phaser.arrive() < 0);
293 assertTrue(phaser.register() < 0);
294 assertTrue(phaser.arriveAndDeregister() < 0);
295 assertTrue(phaser.awaitAdvance(1) < 0);
296 assertTrue(phaser.getPhase() < 0);
297 }
298
299 /**
300 * arriveAndDeregister() throws IllegalStateException if number of
301 * registered or unarrived parties would become negative
302 */
303 public void testArriveAndDeregister1() {
304 try {
305 Phaser phaser = new Phaser();
306 phaser.arriveAndDeregister();
307 shouldThrow();
308 } catch (IllegalStateException success) {}
309 }
310
311 /**
312 * arriveAndDeregister reduces the number of arrived parties
313 */
314 public void testArriveAndDeregister2() {
315 final Phaser phaser = new Phaser(1);
316 assertEquals(0, phaser.register());
317 assertEquals(0, phaser.arrive());
318 assertState(phaser, 0, 2, 1);
319 assertEquals(0, phaser.arriveAndDeregister());
320 assertState(phaser, 1, 1, 1);
321 }
322
323 /**
324 * arriveAndDeregister arrives at the barrier on a phaser with a parent and
325 * when a deregistration occurs and causes the phaser to have zero parties
326 * its parent will be deregistered as well
327 */
328 public void testArriveAndDeregister3() {
329 Phaser parent = new Phaser();
330 Phaser child = new Phaser(parent);
331 assertState(child, 0, 0, 0);
332 assertState(parent, 0, 0, 0);
333 assertEquals(0, child.register());
334 assertState(child, 0, 1, 1);
335 assertState(parent, 0, 1, 1);
336 assertEquals(0, child.arriveAndDeregister());
337 assertTerminated(child);
338 assertTerminated(parent);
339 }
340
341 /**
342 * arriveAndDeregister deregisters one party from its parent when
343 * the number of parties of child is zero after deregistration
344 */
345 public void testArriveAndDeregister4() {
346 Phaser parent = new Phaser();
347 Phaser child = new Phaser(parent);
348 assertEquals(0, parent.register());
349 assertEquals(0, child.register());
350 assertState(child, 0, 1, 1);
351 assertState(parent, 0, 2, 2);
352 assertEquals(0, child.arriveAndDeregister());
353 assertState(child, 0, 0, 0);
354 assertState(parent, 0, 1, 1);
355 }
356
357 /**
358 * arriveAndDeregister deregisters one party from its parent when
359 * the number of parties of root is nonzero after deregistration.
360 */
361 public void testArriveAndDeregister5() {
362 Phaser root = new Phaser();
363 Phaser parent = new Phaser(root);
364 Phaser child = new Phaser(parent);
365 assertState(root, 0, 0, 0);
366 assertState(parent, 0, 0, 0);
367 assertState(child, 0, 0, 0);
368 assertEquals(0, child.register());
369 assertState(root, 0, 1, 1);
370 assertState(parent, 0, 1, 1);
371 assertState(child, 0, 1, 1);
372 assertEquals(0, child.arriveAndDeregister());
373 assertTerminated(child);
374 assertTerminated(parent);
375 assertTerminated(root);
376 }
377
378 /**
379 * arriveAndDeregister returns the phase in which it leaves the
380 * phaser in after deregistration
381 */
382 public void testArriveAndDeregister6() throws InterruptedException {
383 final Phaser phaser = new Phaser(2);
384 Thread t = newStartedThread(new CheckedRunnable() {
385 public void realRun() {
386 assertEquals(0, phaser.arrive());
387 }});
388 assertEquals(1, phaser.arriveAndAwaitAdvance());
389 assertState(phaser, 1, 2, 2);
390 assertEquals(1, phaser.arriveAndDeregister());
391 assertState(phaser, 1, 1, 1);
392 assertEquals(1, phaser.arriveAndDeregister());
393 assertTerminated(phaser);
394 awaitTermination(t, SHORT_DELAY_MS);
395 }
396
397 /**
398 * awaitAdvance succeeds upon advance
399 */
400 public void testAwaitAdvance1() {
401 final Phaser phaser = new Phaser(1);
402 assertEquals(0, phaser.arrive());
403 assertEquals(1, phaser.awaitAdvance(0));
404 }
405
406 /**
407 * awaitAdvance with a negative parameter will return without affecting the
408 * phaser
409 */
410 public void testAwaitAdvance2() {
411 Phaser phaser = new Phaser();
412 assertTrue(phaser.awaitAdvance(-1) < 0);
413 assertState(phaser, 0, 0, 0);
414 }
415
416 /**
417 * awaitAdvance continues waiting if interrupted before waiting
418 */
419 public void testAwaitAdvanceAfterInterrupt() throws InterruptedException {
420 final Phaser phaser = new Phaser();
421 assertEquals(0, phaser.register());
422 final CountDownLatch threadStarted = new CountDownLatch(1);
423
424 Thread t = newStartedThread(new CheckedRunnable() {
425 public void realRun() throws InterruptedException {
426 Thread.currentThread().interrupt();
427 assertEquals(0, phaser.register());
428 assertEquals(0, phaser.arrive());
429 threadStarted.countDown();
430 assertTrue(Thread.currentThread().isInterrupted());
431 assertEquals(1, phaser.awaitAdvance(0));
432 assertTrue(Thread.currentThread().isInterrupted());
433 }});
434
435 assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
436 waitForThreadToEnterWaitState(t, SMALL_DELAY_MS);
437 assertEquals(0, phaser.arrive());
438 awaitTermination(t, SMALL_DELAY_MS);
439
440 Thread.currentThread().interrupt();
441 assertEquals(1, phaser.awaitAdvance(0));
442 assertTrue(Thread.interrupted());
443 }
444
445 /**
446 * awaitAdvance continues waiting if interrupted while waiting
447 */
448 public void testAwaitAdvanceBeforeInterrupt() throws InterruptedException {
449 final Phaser phaser = new Phaser();
450 assertEquals(0, phaser.register());
451 final CountDownLatch threadStarted = new CountDownLatch(1);
452
453 Thread t = newStartedThread(new CheckedRunnable() {
454 public void realRun() throws InterruptedException {
455 assertEquals(0, phaser.register());
456 assertEquals(0, phaser.arrive());
457 threadStarted.countDown();
458 assertFalse(Thread.currentThread().isInterrupted());
459 assertEquals(1, phaser.awaitAdvance(0));
460 assertTrue(Thread.currentThread().isInterrupted());
461 }});
462
463 assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
464 waitForThreadToEnterWaitState(t, SMALL_DELAY_MS);
465 t.interrupt();
466 assertEquals(0, phaser.arrive());
467 awaitTermination(t, SMALL_DELAY_MS);
468
469 Thread.currentThread().interrupt();
470 assertEquals(1, phaser.awaitAdvance(0));
471 assertTrue(Thread.interrupted());
472 }
473
474 /**
475 * arriveAndAwaitAdvance continues waiting if interrupted before waiting
476 */
477 public void testArriveAndAwaitAdvanceAfterInterrupt()
478 throws InterruptedException {
479 final Phaser phaser = new Phaser();
480 assertEquals(0, phaser.register());
481 final CountDownLatch threadStarted = new CountDownLatch(1);
482
483 Thread t = newStartedThread(new CheckedRunnable() {
484 public void realRun() throws InterruptedException {
485 Thread.currentThread().interrupt();
486 assertEquals(0, phaser.register());
487 threadStarted.countDown();
488 assertTrue(Thread.currentThread().isInterrupted());
489 assertEquals(1, phaser.arriveAndAwaitAdvance());
490 assertTrue(Thread.currentThread().isInterrupted());
491 }});
492
493 assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
494 waitForThreadToEnterWaitState(t, SMALL_DELAY_MS);
495 Thread.currentThread().interrupt();
496 assertEquals(1, phaser.arriveAndAwaitAdvance());
497 assertTrue(Thread.interrupted());
498 awaitTermination(t, SMALL_DELAY_MS);
499 }
500
501 /**
502 * arriveAndAwaitAdvance continues waiting if interrupted while waiting
503 */
504 public void testArriveAndAwaitAdvanceBeforeInterrupt()
505 throws InterruptedException {
506 final Phaser phaser = new Phaser();
507 assertEquals(0, phaser.register());
508 final CountDownLatch threadStarted = new CountDownLatch(1);
509
510 Thread t = newStartedThread(new CheckedRunnable() {
511 public void realRun() throws InterruptedException {
512 assertEquals(0, phaser.register());
513 threadStarted.countDown();
514 assertFalse(Thread.currentThread().isInterrupted());
515 assertEquals(1, phaser.arriveAndAwaitAdvance());
516 assertTrue(Thread.currentThread().isInterrupted());
517 }});
518
519 assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
520 waitForThreadToEnterWaitState(t, SMALL_DELAY_MS);
521 t.interrupt();
522 Thread.currentThread().interrupt();
523 assertEquals(1, phaser.arriveAndAwaitAdvance());
524 assertTrue(Thread.interrupted());
525 awaitTermination(t, SMALL_DELAY_MS);
526 }
527
528 /**
529 * awaitAdvance atomically waits for all parties within the same phase to
530 * complete before continuing
531 */
532 public void testAwaitAdvance4() throws InterruptedException {
533 final Phaser phaser = new Phaser(4);
534 final AtomicInteger count = new AtomicInteger(0);
535 List<Thread> threads = new ArrayList<Thread>();
536 for (int i = 0; i < 4; i++)
537 threads.add(newStartedThread(new CheckedRunnable() {
538 public void realRun() {
539 for (int k = 0; k < 3; k++) {
540 assertEquals(2*k+1, phaser.arriveAndAwaitAdvance());
541 count.incrementAndGet();
542 assertEquals(2*k+1, phaser.arrive());
543 assertEquals(2*k+2, phaser.awaitAdvance(2*k+1));
544 assertEquals(count.get(), 4*(k+1));
545 }}}));
546
547 for (Thread thread : threads)
548 awaitTermination(thread, MEDIUM_DELAY_MS);
549 }
550
551 /**
552 * awaitAdvance returns the current phase
553 */
554 public void testAwaitAdvance5() throws InterruptedException {
555 final Phaser phaser = new Phaser(1);
556 assertEquals(1, phaser.awaitAdvance(phaser.arrive()));
557 assertEquals(1, phaser.getPhase());
558 assertEquals(1, phaser.register());
559 List<Thread> threads = new ArrayList<Thread>();
560 for (int i = 0; i < 8; i++) {
561 final CountDownLatch latch = new CountDownLatch(1);
562 final boolean goesFirst = ((i & 1) == 0);
563 threads.add(newStartedThread(new CheckedRunnable() {
564 public void realRun() throws InterruptedException {
565 if (goesFirst)
566 latch.countDown();
567 else
568 assertTrue(latch.await(SMALL_DELAY_MS, MILLISECONDS));
569 phaser.arrive();
570 }}));
571 if (goesFirst)
572 assertTrue(latch.await(SMALL_DELAY_MS, MILLISECONDS));
573 else
574 latch.countDown();
575 assertEquals(i + 2, phaser.awaitAdvance(phaser.arrive()));
576 assertEquals(i + 2, phaser.getPhase());
577 }
578 for (Thread thread : threads)
579 awaitTermination(thread, SMALL_DELAY_MS);
580 }
581
582 /**
583 * awaitAdvance returns when the phaser is externally terminated
584 */
585 public void testAwaitAdvance6() throws InterruptedException {
586 final Phaser phaser = new Phaser(3);
587 final CountDownLatch threadsStarted = new CountDownLatch(2);
588 final List<Thread> threads = new ArrayList<Thread>();
589 for (int i = 0; i < 2; i++) {
590 Runnable r = new CheckedRunnable() {
591 public void realRun() {
592 assertEquals(0, phaser.arrive());
593 threadsStarted.countDown();
594 assertTrue(phaser.awaitAdvance(0) < 0);
595 assertTrue(phaser.isTerminated());
596 assertTrue(phaser.getPhase() < 0);
597 assertEquals(3, phaser.getRegisteredParties());
598 }};
599 threads.add(newStartedThread(r));
600 }
601 threadsStarted.await();
602 phaser.forceTermination();
603 for (Thread thread : threads)
604 awaitTermination(thread, SMALL_DELAY_MS);
605 assertTrue(phaser.isTerminated());
606 assertTrue(phaser.getPhase() < 0);
607 assertEquals(3, phaser.getRegisteredParties());
608 }
609
610 /**
611 * arriveAndAwaitAdvance throws IllegalStateException with no
612 * unarrived parties
613 */
614 public void testArriveAndAwaitAdvance1() {
615 try {
616 Phaser phaser = new Phaser();
617 phaser.arriveAndAwaitAdvance();
618 shouldThrow();
619 } catch (IllegalStateException success) {}
620 }
621
622 /**
623 * arriveAndAwaitAdvance waits for all threads to arrive, the
624 * number of arrived parties is the same number that is accounted
625 * for when the main thread awaitsAdvance
626 */
627 public void testArriveAndAwaitAdvance3() throws InterruptedException {
628 final Phaser phaser = new Phaser(1);
629 final int THREADS = 3;
630 final CountDownLatch threadsStarted = new CountDownLatch(THREADS);
631 final List<Thread> threads = new ArrayList<Thread>();
632 for (int i = 0; i < THREADS; i++)
633 threads.add(newStartedThread(new CheckedRunnable() {
634 public void realRun() throws InterruptedException {
635 assertEquals(0, phaser.register());
636 threadsStarted.countDown();
637 assertEquals(1, phaser.arriveAndAwaitAdvance());
638 }}));
639
640 assertTrue(threadsStarted.await(MEDIUM_DELAY_MS, MILLISECONDS));
641 long t0 = System.nanoTime();
642 while (phaser.getArrivedParties() < THREADS)
643 Thread.yield();
644 assertEquals(THREADS, phaser.getArrivedParties());
645 assertTrue(NANOSECONDS.toMillis(System.nanoTime() - t0) < SMALL_DELAY_MS);
646 for (Thread thread : threads)
647 assertTrue(thread.isAlive());
648 assertState(phaser, 0, THREADS + 1, 1);
649 phaser.arriveAndAwaitAdvance();
650 for (Thread thread : threads)
651 awaitTermination(thread, SMALL_DELAY_MS);
652 assertState(phaser, 1, THREADS + 1, THREADS + 1);
653 }
654
655 }