ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/PhaserTest.java
Revision: 1.13
Committed: Wed Dec 2 19:02:37 2009 UTC (14 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.12: +1 -1 lines
Log Message:
reduce delay in testArriveAndAwaitAdvance3

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.*;
12 import junit.framework.Test;
13 import junit.framework.TestSuite;
14
15 public class PhaserTest extends JSR166TestCase {
16
17 public static void main(String[] args) {
18 junit.textui.TestRunner.run(suite());
19 }
20
21 public static Test suite() {
22 return new TestSuite(PhaserTest.class);
23 }
24
25 /**
26 * Empty constructor builds a new Phaser with no parent, no registered
27 * parties and initial phase number of 0
28 */
29 public void testConstructor1() {
30 Phaser phaser = new Phaser();
31 assertNull(phaser.getParent());
32 assertEquals(0, phaser.getArrivedParties());
33 assertEquals(0, phaser.getPhase());
34 }
35
36 /**
37 * A negative party number for the constructor throws illegal argument
38 * exception
39 */
40 public void testConstructor2() {
41 try {
42 new Phaser(-1);
43 shouldThrow();
44 } catch (IllegalArgumentException success) {}
45 }
46
47 /**
48 * The parent being input into the constructor should equal the original
49 * parent when being returned
50 */
51 public void testConstructor3() {
52 Phaser parent = new Phaser();
53 assertEquals(parent, new Phaser(parent).getParent());
54 }
55
56 /**
57 * A negative party number for the constructor throws illegal argument
58 * exception
59 */
60 public void testConstructor4() {
61 try {
62 new Phaser(new Phaser(), -1);
63 shouldThrow();
64 } catch (IllegalArgumentException success) {}
65 }
66
67 /**
68 * The parent being input into the parameter should equal the original
69 * parent when being returned
70 */
71 public void testConstructor5() {
72 Phaser parent = new Phaser();
73 assertEquals(parent, new Phaser(parent, 0).getParent());
74 }
75
76 /**
77 * register() will increment the number of unarrived parties by one and not
78 * affect its arrived parties
79 */
80 public void testRegister1() {
81 Phaser phaser = new Phaser();
82 assertEquals(0, phaser.getUnarrivedParties());
83 phaser.register();
84 assertEquals(1, phaser.getUnarrivedParties());
85 assertEquals(0, phaser.getArrivedParties());
86 }
87
88 /**
89 * Registering more than 65536 parties causes IllegalStateException
90 */
91 public void testRegister2() {
92 Phaser phaser = new Phaser(0);
93 int expectedUnnarivedParties = (1 << 16) - 1;
94 for (int i = 0; i < expectedUnnarivedParties; i++) {
95 phaser.register();
96 assertEquals(i + 1, phaser.getUnarrivedParties());
97 }
98 try {
99 phaser.register();
100 shouldThrow();
101 } catch (IllegalStateException success) {}
102 }
103
104 /**
105 * register() correctly returns the current barrier phase number when
106 * invoked
107 */
108 public void testRegister3() {
109 Phaser phaser = new Phaser();
110 assertEquals(0, phaser.register());
111 phaser.arrive();
112 assertEquals(1, phaser.register());
113 }
114
115 /**
116 * register causes the next arrive to not increment the phase rather retain
117 * the phase number
118 */
119 public void testRegister4() {
120 Phaser phaser = new Phaser(1);
121 phaser.arrive();
122 int expectedPhase = phaser.register();
123 phaser.arrive();
124 assertEquals(expectedPhase, phaser.getPhase());
125 }
126
127 public void testRegister5() {
128 Phaser phaser = new Phaser();
129 phaser.register();
130 assertEquals(1, phaser.getUnarrivedParties());
131 }
132
133 /**
134 * Invoking bulkRegister with a negative parameter throws an
135 * IllegalArgumentException
136 */
137 public void testBulkRegister1() {
138 try {
139 new Phaser().bulkRegister(-1);
140 shouldThrow();
141 } catch (IllegalArgumentException success) {}
142 }
143
144 /**
145 * bulkRegister should correctly record the number of unarrived parties with
146 * the number of parties being registered
147 */
148 public void testBulkRegister2() {
149 Phaser phaser = new Phaser();
150 phaser.bulkRegister(20);
151 assertEquals(20, phaser.getUnarrivedParties());
152 }
153
154 /**
155 * Registering with a number of parties greater than or equal to 1<<16
156 * throws IllegalStateException.
157 */
158 public void testBulkRegister3() {
159 try {
160 new Phaser().bulkRegister(1 << 16);
161 shouldThrow();
162 } catch (IllegalStateException success) {}
163 }
164
165 /**
166 * the phase number increments correctly when tripping the barrier
167 */
168 public void testPhaseIncrement1() {
169 for (int size = 1; size < nine; size++) {
170 final Phaser phaser = new Phaser(size);
171 for (int index = 0; index <= (1 << size); index++) {
172 int phase = phaser.arrive();
173 assertTrue(index % size == 0 ? (index / size) == phase : index - (phase * size) > 0);
174 }
175 }
176 }
177
178 /**
179 * Arrive() on a registered phaser increments phase.
180 */
181 public void testArrive1() {
182 Phaser phaser = new Phaser(1);
183 phaser.arrive();
184 assertEquals(1, phaser.getPhase());
185 }
186
187 /**
188 * arriveAndDeregister does not wait for others to arrive at barrier
189 */
190 public void testArrive2() throws InterruptedException {
191 final Phaser phaser = new Phaser(1);
192 phaser.register();
193 List<Thread> threads = new ArrayList<Thread>();
194 for (int i = 0; i < 10; i++)
195 phaser.register();
196 threads.add(newStartedThread(new CheckedRunnable() {
197 public void realRun() throws InterruptedException {
198 Thread.sleep(SMALL_DELAY_MS);
199 phaser.arriveAndDeregister();
200 }}));
201
202 phaser.arrive();
203 assertTrue(threads.get(0).isAlive());
204 assertFalse(phaser.isTerminated());
205 for (Thread thread : threads)
206 thread.join();
207 }
208
209 /**
210 * arrive() returns a negative number if the Phaser is terminated
211 */
212 public void testArrive3() {
213 Phaser phaser = new Phaser(1);
214 phaser.forceTermination();
215 assertTrue(phaser.arrive() < 0);
216 }
217
218 /**
219 * arriveAndDeregister() throws IllegalStateException if number of
220 * registered or unarrived parties would become negative
221 */
222 public void testArriveAndDeregister1() {
223 try {
224 Phaser phaser = new Phaser();
225 phaser.arriveAndDeregister();
226 shouldThrow();
227 } catch (IllegalStateException success) {}
228 }
229
230 /**
231 * arriveAndDeregister deregisters reduces the number of arrived parties
232 */
233 public void testArriveAndDergeister2() {
234 final Phaser phaser = new Phaser(1);
235 phaser.register();
236 phaser.arrive();
237 int p = phaser.getArrivedParties();
238 assertTrue(p == 1);
239 phaser.arriveAndDeregister();
240 assertTrue(phaser.getArrivedParties() < p);
241 }
242
243 /**
244 * arriveAndDeregister arrives to the barrier on a phaser with a parent and
245 * when a deregistration occurs and causes the phaser to have zero parties
246 * its parent will be deregistered as well
247 */
248 public void testArriveAndDeregsiter3() {
249 Phaser parent = new Phaser();
250 Phaser root = new Phaser(parent);
251 root.register();
252 assertTrue(parent.getUnarrivedParties() > 0);
253 assertTrue(root.getUnarrivedParties() > 0);
254 root.arriveAndDeregister();
255 assertTrue(parent.getUnarrivedParties() == 0);
256 assertTrue(root.getUnarrivedParties() == 0);
257 assertTrue(root.isTerminated() && parent.isTerminated());
258 }
259
260 /**
261 * arriveAndDeregister deregisters one party from its parent when
262 * the number of parties of root is zero after deregistration
263 */
264 public void testArriveAndDeregsiter4() {
265 Phaser parent = new Phaser();
266 Phaser root = new Phaser(parent);
267 parent.register();
268 root.register();
269 int parentParties = parent.getUnarrivedParties();
270 root.arriveAndDeregister();
271 assertEquals(parentParties - 1, parent.getUnarrivedParties());
272 }
273
274 /**
275 * arriveAndDeregister deregisters one party from its parent when
276 * the number of parties of root is nonzero after deregistration.
277 */
278 public void testArriveAndDeregister5() {
279 Phaser parent = new Phaser();
280 Phaser child = new Phaser(parent);
281 Phaser root = new Phaser(child);
282 assertTrue(parent.getUnarrivedParties() > 0);
283 assertTrue(child.getUnarrivedParties() > 0);
284 root.register();
285 root.arriveAndDeregister();
286 assertTrue(parent.getUnarrivedParties() == 0);
287 assertTrue(child.getUnarrivedParties() == 0);
288 assertTrue(root.isTerminated());
289 }
290
291 /**
292 * arriveAndDeregister returns the phase in which it leaves the
293 * phaser in after deregistration
294 */
295 public void testArriveAndDeregister6() throws InterruptedException {
296 final Phaser phaser = new Phaser(2);
297 Thread t = newStartedThread(new CheckedRunnable() {
298 public void realRun() {
299 sleepTillInterrupted(SHORT_DELAY_MS);
300 phaser.arrive();
301 }});
302 phaser.arriveAndAwaitAdvance();
303 int phase = phaser.arriveAndDeregister();
304 assertEquals(phase, phaser.getPhase());
305 t.join();
306 }
307
308 /**
309 * awaitAdvance succeeds upon advance
310 */
311 public void testAwaitAdvance1() {
312 final Phaser phaser = new Phaser(1);
313 phaser.awaitAdvance(phaser.arrive());
314 }
315
316 /**
317 * awaitAdvance with a negative parameter will return without affecting the
318 * phaser
319 */
320 public void testAwaitAdvance2() {
321 Phaser phaser = new Phaser();
322 phaser.awaitAdvance(-1);
323 }
324
325 /**
326 * awaitAdvance while waiting does not abort on interrupt.
327 */
328 public void testAwaitAdvance3() throws InterruptedException {
329 final Phaser phaser = new Phaser();
330 phaser.register();
331
332 Thread t = newStartedThread(new CheckedRunnable() {
333 public void realRun() throws InterruptedException {
334 phaser.register();
335 sleepTillInterrupted(LONG_DELAY_MS);
336 phaser.awaitAdvance(phaser.arrive());
337 }});
338 Thread.sleep(SMALL_DELAY_MS);
339 t.interrupt();
340 Thread.sleep(SMALL_DELAY_MS);
341 phaser.arrive();
342 assertFalse(t.isInterrupted());
343 t.join();
344 }
345
346 /**
347 * awaitAdvance atomically waits for all parties within the same phase to
348 * complete before continuing
349 */
350 public void testAwaitAdvance4() throws InterruptedException {
351 final Phaser phaser = new Phaser(4);
352 final AtomicInteger phaseCount = new AtomicInteger(0);
353 List<Thread> threads = new ArrayList<Thread>();
354 for (int i = 0; i < 4; i++) {
355 threads.add(newStartedThread(new CheckedRunnable() {
356 public void realRun() {
357 int phase = phaser.arrive();
358 phaseCount.incrementAndGet();
359 sleepTillInterrupted(SMALL_DELAY_MS);
360 phaser.awaitAdvance(phase);
361 assertEquals(phaseCount.get(), 4);
362 }}));
363 }
364 for (Thread thread : threads)
365 thread.join();
366 }
367
368 /**
369 * awaitAdvance returns the current phase
370 */
371 public void testAwaitAdvance5() throws InterruptedException {
372 final Phaser phaser = new Phaser(1);
373 int phase = phaser.awaitAdvance(phaser.arrive());
374 assertEquals(phase, phaser.getPhase());
375 phaser.register();
376 List<Thread> threads = new ArrayList<Thread>();
377 for (int i = 0; i < 8; i++) {
378 threads.add(newStartedThread(new CheckedRunnable() {
379 public void realRun() {
380 sleepTillInterrupted(SHORT_DELAY_MS);
381 phaser.arrive();
382 }}));
383 phase = phaser.awaitAdvance(phaser.arrive());
384 assertEquals(phase, phaser.getPhase());
385 }
386 for (Thread thread : threads)
387 thread.join();
388 }
389
390 /**
391 * awaitAdvance returns when the phaser is externally terminated
392 */
393 public void testAwaitAdvance6() throws InterruptedException {
394 final Phaser phaser = new Phaser(3);
395 /*
396 * Start new thread. This thread waits a small amount of time
397 * and waits for the other two parties to arrive. The party
398 * in the main thread arrives quickly so at best this thread
399 * waits for the second thread's party to arrive
400 */
401 Thread t1 = newStartedThread(new CheckedRunnable() {
402 public void realRun() {
403 sleepTillInterrupted(SMALL_DELAY_MS);
404 int phase = phaser.awaitAdvance(phaser.arrive());
405 /*
406 * This point is reached when force termination is called in which phase = -1
407 */
408 assertTrue(phase < 0);
409 assertTrue(phaser.isTerminated());
410 }});
411 /*
412 * This thread will cause the first thread run to wait, in doing so
413 * the main thread will force termination in which the first thread
414 * should exit peacefully as this one
415 */
416 Thread t2 = newStartedThread(new CheckedRunnable() {
417 public void realRun() {
418 sleepTillInterrupted(MEDIUM_DELAY_MS);
419 int p1 = phaser.arrive();
420 int phase = phaser.awaitAdvance(p1);
421 assertTrue(phase < 0);
422 assertTrue(phaser.isTerminated());
423 }});
424
425 phaser.arrive();
426 phaser.forceTermination();
427 t1.join();
428 t2.join();
429 }
430
431 /**
432 * arriveAndAwaitAdvance throws IllegalStateException with no
433 * unarrived parties
434 */
435 public void testArriveAndAwaitAdvance1() {
436 try {
437 Phaser phaser = new Phaser();
438 phaser.arriveAndAwaitAdvance();
439 shouldThrow();
440 } catch (IllegalStateException success) {}
441 }
442
443 /**
444 * Interrupted arriveAndAwaitAdvance does not throw InterruptedException
445 */
446 public void testArriveAndAwaitAdvance2() throws InterruptedException {
447 final Phaser phaser = new Phaser(2);
448 Thread th = newStartedThread(new CheckedRunnable() {
449 public void realRun() {
450 phaser.arriveAndAwaitAdvance();
451 }});
452
453 Thread.sleep(SMALL_DELAY_MS);
454 th.interrupt();
455 Thread.sleep(SMALL_DELAY_MS);
456 phaser.arrive();
457 assertFalse(th.isInterrupted());
458 th.join();
459 }
460
461 /**
462 * arriveAndAwaitAdvance waits for all threads to arrive, the
463 * number of arrived parties is the same number that is accounted
464 * for when the main thread awaitsAdvance
465 */
466 public void testArriveAndAwaitAdvance3() throws InterruptedException {
467 final Phaser phaser = new Phaser(1);
468 final List<Thread> threads = new ArrayList<Thread>();
469 for (int i = 0; i < 3; i++) {
470 threads.add(newStartedThread(new CheckedRunnable() {
471 public void realRun() throws InterruptedException {
472 phaser.register();
473 phaser.arriveAndAwaitAdvance();
474 }}));
475 }
476 Thread.sleep(MEDIUM_DELAY_MS);
477 assertEquals(phaser.getArrivedParties(), 3);
478 phaser.arriveAndAwaitAdvance();
479 for (Thread thread : threads)
480 thread.join();
481 }
482
483 }