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.1 by dl, Sun Aug 31 19:24:54 2003 UTC vs.
Revision 1.20 by jsr166, Fri May 27 20:07:24 2011 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines