ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/CyclicBarrierTest.java
Revision: 1.23
Committed: Sun May 29 15:31:36 2011 UTC (12 years, 11 months ago) by jsr166
Branch: MAIN
Changes since 1.22: +18 -8 lines
Log Message:
fix flaky testReset_BrokenBarrier

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/publicdomain/zero/1.0/
5 * Other contributors include Andrew Wright, Jeffrey Hayes,
6 * Pat Fisher, Mike Judd.
7 */
8
9 import junit.framework.*;
10 import java.util.*;
11 import java.util.concurrent.*;
12 import java.util.concurrent.locks.*;
13 import java.util.concurrent.atomic.*;
14 import static java.util.concurrent.TimeUnit.MILLISECONDS;
15
16 public class CyclicBarrierTest extends JSR166TestCase {
17 public static void main(String[] args) {
18 junit.textui.TestRunner.run(suite());
19 }
20 public static Test suite() {
21 return new TestSuite(CyclicBarrierTest.class);
22 }
23
24 private volatile int countAction;
25 private class MyAction implements Runnable {
26 public void run() { ++countAction; }
27 }
28
29 /**
30 * Spin-waits till the number of waiters == numberOfWaiters.
31 */
32 void awaitNumberWaiting(CyclicBarrier barrier, int numberOfWaiters) {
33 long startTime = System.nanoTime();
34 while (barrier.getNumberWaiting() != numberOfWaiters) {
35 if (millisElapsedSince(startTime) > LONG_DELAY_MS)
36 fail("timed out");
37 Thread.yield();
38 }
39 }
40
41 /**
42 * Creating with negative parties throws IAE
43 */
44 public void testConstructor1() {
45 try {
46 new CyclicBarrier(-1, (Runnable)null);
47 shouldThrow();
48 } catch (IllegalArgumentException success) {}
49 }
50
51 /**
52 * Creating with negative parties and no action throws IAE
53 */
54 public void testConstructor2() {
55 try {
56 new CyclicBarrier(-1);
57 shouldThrow();
58 } catch (IllegalArgumentException success) {}
59 }
60
61 /**
62 * getParties returns the number of parties given in constructor
63 */
64 public void testGetParties() {
65 CyclicBarrier b = new CyclicBarrier(2);
66 assertEquals(2, b.getParties());
67 assertEquals(0, b.getNumberWaiting());
68 }
69
70 /**
71 * A 1-party barrier triggers after single await
72 */
73 public void testSingleParty() throws Exception {
74 CyclicBarrier b = new CyclicBarrier(1);
75 assertEquals(1, b.getParties());
76 assertEquals(0, b.getNumberWaiting());
77 b.await();
78 b.await();
79 assertEquals(0, b.getNumberWaiting());
80 }
81
82 /**
83 * The supplied barrier action is run at barrier
84 */
85 public void testBarrierAction() throws Exception {
86 countAction = 0;
87 CyclicBarrier b = new CyclicBarrier(1, new MyAction());
88 assertEquals(1, b.getParties());
89 assertEquals(0, b.getNumberWaiting());
90 b.await();
91 b.await();
92 assertEquals(0, b.getNumberWaiting());
93 assertEquals(countAction, 2);
94 }
95
96 /**
97 * A 2-party/thread barrier triggers after both threads invoke await
98 */
99 public void testTwoParties() throws Exception {
100 final CyclicBarrier b = new CyclicBarrier(2);
101 Thread t = newStartedThread(new CheckedRunnable() {
102 public void realRun() throws Exception {
103 b.await();
104 b.await();
105 b.await();
106 b.await();
107 }});
108
109 b.await();
110 b.await();
111 b.await();
112 b.await();
113 awaitTermination(t);
114 }
115
116 /**
117 * An interruption in one party causes others waiting in await to
118 * throw BrokenBarrierException
119 */
120 public void testAwait1_Interrupted_BrokenBarrier() {
121 final CyclicBarrier c = new CyclicBarrier(3);
122 final CountDownLatch pleaseInterrupt = new CountDownLatch(2);
123 Thread t1 = new ThreadShouldThrow(InterruptedException.class) {
124 public void realRun() throws Exception {
125 pleaseInterrupt.countDown();
126 c.await();
127 }};
128 Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
129 public void realRun() throws Exception {
130 pleaseInterrupt.countDown();
131 c.await();
132 }};
133
134 t1.start();
135 t2.start();
136 await(pleaseInterrupt);
137 t1.interrupt();
138 awaitTermination(t1);
139 awaitTermination(t2);
140 }
141
142 /**
143 * An interruption in one party causes others waiting in timed await to
144 * throw BrokenBarrierException
145 */
146 public void testAwait2_Interrupted_BrokenBarrier() throws Exception {
147 final CyclicBarrier c = new CyclicBarrier(3);
148 final CountDownLatch pleaseInterrupt = new CountDownLatch(2);
149 Thread t1 = new ThreadShouldThrow(InterruptedException.class) {
150 public void realRun() throws Exception {
151 pleaseInterrupt.countDown();
152 c.await(LONG_DELAY_MS, MILLISECONDS);
153 }};
154 Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
155 public void realRun() throws Exception {
156 pleaseInterrupt.countDown();
157 c.await(LONG_DELAY_MS, MILLISECONDS);
158 }};
159
160 t1.start();
161 t2.start();
162 await(pleaseInterrupt);
163 t1.interrupt();
164 awaitTermination(t1);
165 awaitTermination(t2);
166 }
167
168 /**
169 * A timeout in timed await throws TimeoutException
170 */
171 public void testAwait3_TimeoutException() throws InterruptedException {
172 final CyclicBarrier c = new CyclicBarrier(2);
173 Thread t = newStartedThread(new CheckedRunnable() {
174 public void realRun() throws Exception {
175 long startTime = System.nanoTime();
176 try {
177 c.await(timeoutMillis(), MILLISECONDS);
178 shouldThrow();
179 } catch (TimeoutException success) {}
180 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
181 }});
182
183 awaitTermination(t);
184 }
185
186 /**
187 * A timeout in one party causes others waiting in timed await to
188 * throw BrokenBarrierException
189 */
190 public void testAwait4_Timeout_BrokenBarrier() throws InterruptedException {
191 final CyclicBarrier c = new CyclicBarrier(3);
192 Thread t1 = newStartedThread(new CheckedRunnable() {
193 public void realRun() throws Exception {
194 try {
195 c.await(LONG_DELAY_MS, MILLISECONDS);
196 shouldThrow();
197 } catch (BrokenBarrierException success) {}
198 }});
199 Thread t2 = newStartedThread(new CheckedRunnable() {
200 public void realRun() throws Exception {
201 awaitNumberWaiting(c, 1);
202 long startTime = System.nanoTime();
203 try {
204 c.await(timeoutMillis(), MILLISECONDS);
205 shouldThrow();
206 } catch (TimeoutException success) {}
207 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
208 }});
209
210 awaitTermination(t1);
211 awaitTermination(t2);
212 }
213
214 /**
215 * A timeout in one party causes others waiting in await to
216 * throw BrokenBarrierException
217 */
218 public void testAwait5_Timeout_BrokenBarrier() throws InterruptedException {
219 final CyclicBarrier c = new CyclicBarrier(3);
220 Thread t1 = newStartedThread(new CheckedRunnable() {
221 public void realRun() throws Exception {
222 try {
223 c.await();
224 shouldThrow();
225 } catch (BrokenBarrierException success) {}
226 }});
227 Thread t2 = newStartedThread(new CheckedRunnable() {
228 public void realRun() throws Exception {
229 awaitNumberWaiting(c, 1);
230 long startTime = System.nanoTime();
231 try {
232 c.await(timeoutMillis(), MILLISECONDS);
233 shouldThrow();
234 } catch (TimeoutException success) {}
235 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
236 }});
237
238 awaitTermination(t1);
239 awaitTermination(t2);
240 }
241
242 /**
243 * A reset of an active barrier causes waiting threads to throw
244 * BrokenBarrierException
245 */
246 public void testReset_BrokenBarrier() throws InterruptedException {
247 final CyclicBarrier c = new CyclicBarrier(3);
248 final CountDownLatch pleaseReset = new CountDownLatch(2);
249 Thread t1 = new ThreadShouldThrow(BrokenBarrierException.class) {
250 public void realRun() throws Exception {
251 pleaseReset.countDown();
252 c.await();
253 }};
254 Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
255 public void realRun() throws Exception {
256 pleaseReset.countDown();
257 c.await();
258 }};
259
260 t1.start();
261 t2.start();
262 await(pleaseReset);
263
264 awaitNumberWaiting(c, 2);
265 c.reset();
266 awaitTermination(t1);
267 awaitTermination(t2);
268 }
269
270 /**
271 * A reset before threads enter barrier does not throw
272 * BrokenBarrierException
273 */
274 public void testReset_NoBrokenBarrier() throws Exception {
275 final CyclicBarrier c = new CyclicBarrier(3);
276 c.reset();
277
278 Thread t1 = newStartedThread(new CheckedRunnable() {
279 public void realRun() throws Exception {
280 c.await();
281 }});
282 Thread t2 = newStartedThread(new CheckedRunnable() {
283 public void realRun() throws Exception {
284 c.await();
285 }});
286
287 c.await();
288 awaitTermination(t1);
289 awaitTermination(t2);
290 }
291
292 /**
293 * All threads block while a barrier is broken.
294 */
295 public void testReset_Leakage() throws InterruptedException {
296 final CyclicBarrier c = new CyclicBarrier(2);
297 final AtomicBoolean done = new AtomicBoolean();
298 Thread t = newStartedThread(new CheckedRunnable() {
299 public void realRun() {
300 while (!done.get()) {
301 try {
302 while (c.isBroken())
303 c.reset();
304
305 c.await();
306 shouldThrow();
307 }
308 catch (BrokenBarrierException ok) {}
309 catch (InterruptedException ok) {}
310 }}});
311
312 for (int i = 0; i < 4; i++) {
313 delay(timeoutMillis());
314 t.interrupt();
315 }
316 done.set(true);
317 t.interrupt();
318 awaitTermination(t);
319 }
320
321 /**
322 * Reset of a non-broken barrier does not break barrier
323 */
324 public void testResetWithoutBreakage() throws Exception {
325 final CyclicBarrier barrier = new CyclicBarrier(3);
326 for (int i = 0; i < 3; i++) {
327 final CyclicBarrier start = new CyclicBarrier(3);
328 Thread t1 = newStartedThread(new CheckedRunnable() {
329 public void realRun() throws Exception {
330 start.await();
331 barrier.await();
332 }});
333
334 Thread t2 = newStartedThread(new CheckedRunnable() {
335 public void realRun() throws Exception {
336 start.await();
337 barrier.await();
338 }});
339
340 start.await();
341 barrier.await();
342 awaitTermination(t1);
343 awaitTermination(t2);
344 assertFalse(barrier.isBroken());
345 assertEquals(0, barrier.getNumberWaiting());
346 if (i == 1) barrier.reset();
347 assertFalse(barrier.isBroken());
348 assertEquals(0, barrier.getNumberWaiting());
349 }
350 }
351
352 /**
353 * Reset of a barrier after interruption reinitializes it.
354 */
355 public void testResetAfterInterrupt() throws Exception {
356 final CyclicBarrier barrier = new CyclicBarrier(3);
357 for (int i = 0; i < 2; i++) {
358 final CyclicBarrier start = new CyclicBarrier(3);
359 Thread t1 = new ThreadShouldThrow(InterruptedException.class) {
360 public void realRun() throws Exception {
361 start.await();
362 barrier.await();
363 }};
364
365 Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
366 public void realRun() throws Exception {
367 start.await();
368 barrier.await();
369 }};
370
371 t1.start();
372 t2.start();
373 start.await();
374 t1.interrupt();
375 awaitTermination(t1);
376 awaitTermination(t2);
377 assertTrue(barrier.isBroken());
378 assertEquals(0, barrier.getNumberWaiting());
379 barrier.reset();
380 assertFalse(barrier.isBroken());
381 assertEquals(0, barrier.getNumberWaiting());
382 }
383 }
384
385 /**
386 * Reset of a barrier after timeout reinitializes it.
387 */
388 public void testResetAfterTimeout() throws Exception {
389 final CyclicBarrier barrier = new CyclicBarrier(3);
390 for (int i = 0; i < 2; i++) {
391 assertEquals(0, barrier.getNumberWaiting());
392 Thread t1 = newStartedThread(new CheckedRunnable() {
393 public void realRun() throws Exception {
394 try {
395 barrier.await();
396 shouldThrow();
397 } catch (BrokenBarrierException success) {}
398 }});
399 Thread t2 = newStartedThread(new CheckedRunnable() {
400 public void realRun() throws Exception {
401 awaitNumberWaiting(barrier, 1);
402 long startTime = System.nanoTime();
403 try {
404 barrier.await(timeoutMillis(), MILLISECONDS);
405 shouldThrow();
406 } catch (TimeoutException success) {}
407 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
408 }});
409
410 awaitTermination(t1);
411 awaitTermination(t2);
412 assertEquals(0, barrier.getNumberWaiting());
413 assertTrue(barrier.isBroken());
414 assertEquals(0, barrier.getNumberWaiting());
415 barrier.reset();
416 assertFalse(barrier.isBroken());
417 assertEquals(0, barrier.getNumberWaiting());
418 }
419 }
420
421 /**
422 * Reset of a barrier after a failed command reinitializes it.
423 */
424 public void testResetAfterCommandException() throws Exception {
425 final CyclicBarrier barrier =
426 new CyclicBarrier(3, new Runnable() {
427 public void run() {
428 throw new NullPointerException(); }});
429 for (int i = 0; i < 2; i++) {
430 final CyclicBarrier start = new CyclicBarrier(3);
431 Thread t1 = new ThreadShouldThrow(BrokenBarrierException.class) {
432 public void realRun() throws Exception {
433 start.await();
434 barrier.await();
435 }};
436
437 Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
438 public void realRun() throws Exception {
439 start.await();
440 barrier.await();
441 }};
442
443 t1.start();
444 t2.start();
445 start.await();
446 awaitNumberWaiting(barrier, 2);
447 try {
448 barrier.await();
449 shouldThrow();
450 } catch (NullPointerException success) {}
451 awaitTermination(t1);
452 awaitTermination(t2);
453 assertTrue(barrier.isBroken());
454 assertEquals(0, barrier.getNumberWaiting());
455 barrier.reset();
456 assertFalse(barrier.isBroken());
457 assertEquals(0, barrier.getNumberWaiting());
458 }
459 }
460 }