ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/CyclicBarrierTest.java
(Generate patch)

Comparing jsr166/src/test/tck/CyclicBarrierTest.java (file contents):
Revision 1.13 by jsr166, Sat Nov 21 02:33:20 2009 UTC vs.
Revision 1.34 by jsr166, Mon Sep 9 00:46:44 2019 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines