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.21 by jsr166, Sat May 28 14:52:11 2011 UTC vs.
Revision 1.33 by jsr166, Mon Sep 9 00:03:07 2019 UTC

# Line 6 | Line 6
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.AtomicBoolean;
19 + import java.util.concurrent.atomic.AtomicInteger;
20 +
21 + import junit.framework.Test;
22 + import junit.framework.TestSuite;
23 +
24   public class CyclicBarrierTest extends JSR166TestCase {
25      public static void main(String[] args) {
26 <        junit.textui.TestRunner.run(suite());
26 >        main(suite(), args);
27      }
28      public static Test suite() {
29          return new TestSuite(CyclicBarrierTest.class);
30      }
31  
32 <    private volatile int countAction;
33 <    private class MyAction implements Runnable {
34 <        public void run() { ++countAction; }
32 >    /**
33 >     * Spin-waits till the number of waiters == numberOfWaiters.
34 >     */
35 >    void awaitNumberWaiting(CyclicBarrier barrier, int numberOfWaiters) {
36 >        long startTime = System.nanoTime();
37 >        while (barrier.getNumberWaiting() != numberOfWaiters) {
38 >            if (millisElapsedSince(startTime) > LONG_DELAY_MS)
39 >                fail("timed out");
40 >            Thread.yield();
41 >        }
42      }
43  
44      /**
45 <     * Creating with negative parties throws IAE
45 >     * Creating with negative parties throws IllegalArgumentException
46       */
47      public void testConstructor1() {
48          try {
# Line 37 | Line 52 | public class CyclicBarrierTest extends J
52      }
53  
54      /**
55 <     * Creating with negative parties and no action throws IAE
55 >     * Creating with negative parties and no action throws
56 >     * IllegalArgumentException
57       */
58      public void testConstructor2() {
59          try {
# Line 71 | Line 87 | public class CyclicBarrierTest extends J
87       * The supplied barrier action is run at barrier
88       */
89      public void testBarrierAction() throws Exception {
90 <        countAction = 0;
91 <        CyclicBarrier b = new CyclicBarrier(1, new MyAction());
90 >        final AtomicInteger count = new AtomicInteger(0);
91 >        final Runnable incCount = new Runnable() { public void run() {
92 >            count.getAndIncrement(); }};
93 >        CyclicBarrier b = new CyclicBarrier(1, incCount);
94          assertEquals(1, b.getParties());
95          assertEquals(0, b.getNumberWaiting());
96          b.await();
97          b.await();
98          assertEquals(0, b.getNumberWaiting());
99 <        assertEquals(countAction, 2);
99 >        assertEquals(2, count.get());
100      }
101  
102      /**
# Line 186 | Line 204 | public class CyclicBarrierTest extends J
204              }});
205          Thread t2 = newStartedThread(new CheckedRunnable() {
206              public void realRun() throws Exception {
207 <                while (c.getNumberWaiting() == 0)
190 <                    Thread.yield();
207 >                awaitNumberWaiting(c, 1);
208                  long startTime = System.nanoTime();
209                  try {
210                      c.await(timeoutMillis(), MILLISECONDS);
# Line 215 | Line 232 | public class CyclicBarrierTest extends J
232              }});
233          Thread t2 = newStartedThread(new CheckedRunnable() {
234              public void realRun() throws Exception {
235 <                while (c.getNumberWaiting() == 0)
219 <                    Thread.yield();
235 >                awaitNumberWaiting(c, 1);
236                  long startTime = System.nanoTime();
237                  try {
238                      c.await(timeoutMillis(), MILLISECONDS);
# Line 250 | Line 266 | public class CyclicBarrierTest extends J
266          t1.start();
267          t2.start();
268          await(pleaseReset);
269 +
270 +        awaitNumberWaiting(c, 2);
271          c.reset();
272          awaitTermination(t1);
273          awaitTermination(t2);
# Line 278 | Line 296 | public class CyclicBarrierTest extends J
296      }
297  
298      /**
281     * All threads block while a barrier is broken.
282     */
283    public void testReset_Leakage() throws InterruptedException {
284        final CyclicBarrier c = new CyclicBarrier(2);
285        final AtomicBoolean done = new AtomicBoolean();
286        Thread t = newStartedThread(new CheckedRunnable() {
287            public void realRun() {
288                while (!done.get()) {
289                    try {
290                        while (c.isBroken())
291                            c.reset();
292
293                        c.await();
294                        shouldThrow();
295                    }
296                    catch (BrokenBarrierException ok) {}
297                    catch (InterruptedException ok) {}
298                }}});
299
300        for (int i = 0; i < 4; i++) {
301            delay(timeoutMillis());
302            t.interrupt();
303        }
304        done.set(true);
305        t.interrupt();
306        awaitTermination(t);
307    }
308
309    /**
299       * Reset of a non-broken barrier does not break barrier
300       */
301      public void testResetWithoutBreakage() throws Exception {
# Line 386 | Line 375 | public class CyclicBarrierTest extends J
375                  }});
376              Thread t2 = newStartedThread(new CheckedRunnable() {
377                  public void realRun() throws Exception {
378 <                    while (barrier.getNumberWaiting() == 0)
390 <                        Thread.yield();
378 >                    awaitNumberWaiting(barrier, 1);
379                      long startTime = System.nanoTime();
380                      try {
381                          barrier.await(timeoutMillis(), MILLISECONDS);
# Line 432 | Line 420 | public class CyclicBarrierTest extends J
420              t1.start();
421              t2.start();
422              start.await();
423 <            while (barrier.getNumberWaiting() < 2) { Thread.yield(); }
423 >            awaitNumberWaiting(barrier, 2);
424              try {
425                  barrier.await();
426                  shouldThrow();
# Line 446 | Line 434 | public class CyclicBarrierTest extends J
434              assertEquals(0, barrier.getNumberWaiting());
435          }
436      }
437 +
438 +    /**
439 +     * There can be more threads calling await() than parties, as long as each
440 +     * task only calls await once and the task count is a multiple of parties.
441 +     */
442 +    public void testMoreTasksThanParties() throws Exception {
443 +        final ThreadLocalRandom rnd = ThreadLocalRandom.current();
444 +        final int parties = rnd.nextInt(1, 5);
445 +        final int nTasks = rnd.nextInt(1, 5) * parties;
446 +        final AtomicInteger tripCount = new AtomicInteger(0);
447 +        final AtomicInteger awaitCount = new AtomicInteger(0);
448 +        final CyclicBarrier barrier =
449 +            new CyclicBarrier(parties, () -> tripCount.getAndIncrement());
450 +        final ExecutorService e = Executors.newFixedThreadPool(nTasks);
451 +        final Runnable awaiter = () -> {
452 +            try {
453 +                if (randomBoolean())
454 +                    barrier.await();
455 +                else
456 +                    barrier.await(LONG_DELAY_MS, MILLISECONDS);
457 +                awaitCount.getAndIncrement();
458 +            } catch (Throwable fail) { threadUnexpectedException(fail); }};
459 +        try (PoolCleaner cleaner = cleaner(e)) {
460 +            for (int i = nTasks; i--> 0; )
461 +                e.execute(awaiter);
462 +        }
463 +        assertEquals(nTasks / parties, tripCount.get());
464 +        assertEquals(nTasks, awaitCount.get());
465 +        assertEquals(0, barrier.getNumberWaiting());
466 +    }
467   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines