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.23 by jsr166, Sun May 29 15:31:36 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 >     * 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 <            fail("should throw");
48 <        } catch(IllegalArgumentException e){}
47 >            shouldThrow();
48 >        } catch (IllegalArgumentException success) {}
49      }
50  
51 <    public void testConstructor2(){
52 <        try{
51 >    /**
52 >     * Creating with negative parties and no action throws IAE
53 >     */
54 >    public void testConstructor2() {
55 >        try {
56              new CyclicBarrier(-1);
57 <            fail("should throw");
58 <        } catch(IllegalArgumentException e){}
57 >            shouldThrow();
58 >        } catch (IllegalArgumentException success) {}
59      }
60  
61 <    public void testConstructor3(){
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());
66 >        assertEquals(2, b.getParties());
67          assertEquals(0, b.getNumberWaiting());
68      }
69  
70 <    public void testSingleParty() {
71 <        try {
72 <            CyclicBarrier b = new CyclicBarrier(1);
73 <            assertEquals(1, b.getParties());
74 <            assertEquals(0, b.getNumberWaiting());
75 <            b.await();
76 <            b.await();
77 <            assertEquals(0, b.getNumberWaiting());
78 <        }
79 <        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; }
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 <    public void testBarrierAction() {
83 <        try {
84 <            countAction = 0;
85 <            CyclicBarrier b = new CyclicBarrier(1, new MyAction());
86 <            assertEquals(1, b.getParties());
87 <            assertEquals(0, b.getNumberWaiting());
88 <            b.await();
89 <            b.await();
90 <            assertEquals(0, b.getNumberWaiting());
91 <            assertEquals(countAction, 2);
92 <        }
93 <        catch(Exception e) {
78 <            fail("unexpected exception");
79 <        }
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 <    public void testTwoParties(){
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 = new Thread(new Runnable() {
102 <                public void run(){
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 <                        b.await();
303 <                        b.await();
90 <                        b.await();
91 <                        b.await();
92 <                    } catch(Exception e){
93 <                        fail("unexpected exception");
94 <                    }}});
302 >                        while (c.isBroken())
303 >                            c.reset();
304  
305 <        try {
306 <            t.start();
307 <            b.await();
308 <            b.await();
309 <            b.await();
310 <            b.await();
311 <            t.join();
312 <        } catch(Exception e){
313 <            fail("unexpected exception");
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  
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 {
371              t1.start();
372              t2.start();
373 <            Thread.sleep(SHORT_DELAY_MS);
373 >            start.await();
374              t1.interrupt();
375 <            t1.join();
376 <            t2.join();
377 <        } catch(InterruptedException e){
378 <            fail("unexpected exception");
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 <    public void testAwait2_Interrupted_BrokenBarrier(){
386 <      final CyclicBarrier c = new CyclicBarrier(3);
387 <        Thread t1 = new Thread(new Runnable() {
388 <                public void run(){
389 <                    try{
390 <                        c.await(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
391 <                        fail("should throw");
392 <                    } catch(InterruptedException success){
393 <                    } catch(Exception b){
394 <                        fail("should throw IE");
395 <                    }
396 <                }
397 <            });
398 <        Thread t2 = new Thread(new Runnable(){
399 <                public void run(){
400 <                    try{
401 <                        c.await(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
402 <                        fail("should throw");                        
403 <                    } catch(BrokenBarrierException success){
404 <                    } catch(Exception i){
405 <                        fail("should throw BBE");
406 <                    }
407 <                }
408 <            });
409 <        try {
410 <            t1.start();
411 <            t2.start();
412 <            Thread.sleep(SHORT_DELAY_MS);
413 <            t1.interrupt();
414 <            t1.join();
415 <            t2.join();
416 <        } catch(InterruptedException e){
417 <            fail("unexpected exception");
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 <    public void testAwait3_TimeOutException(){
422 <        final CyclicBarrier c = new CyclicBarrier(2);
423 <        Thread t = new Thread(new Runnable() {
424 <                public void run(){
425 <                    try{
426 <                        c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
427 <                        fail("should throw");
428 <                    } catch(TimeoutException success){
429 <                    } catch(Exception b){
430 <                        fail("should throw TOE");
431 <                        
432 <                    }
433 <                }
434 <            });
435 <        try {
436 <            t.start();
437 <            t.join();
438 <        } catch(InterruptedException e){
439 <            fail("unexpected exception");
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      }
202    
460   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines