36 import static java.util.concurrent.TimeUnit.MILLISECONDS; |
36 import static java.util.concurrent.TimeUnit.MILLISECONDS; |
37 |
37 |
38 import java.util.concurrent.BrokenBarrierException; |
38 import java.util.concurrent.BrokenBarrierException; |
39 import java.util.concurrent.CountDownLatch; |
39 import java.util.concurrent.CountDownLatch; |
40 import java.util.concurrent.CyclicBarrier; |
40 import java.util.concurrent.CyclicBarrier; |
|
41 import java.util.concurrent.ExecutorService; |
|
42 import java.util.concurrent.Executors; |
|
43 import java.util.concurrent.ThreadLocalRandom; |
41 import java.util.concurrent.TimeoutException; |
44 import java.util.concurrent.TimeoutException; |
42 import java.util.concurrent.atomic.AtomicBoolean; |
45 import java.util.concurrent.atomic.AtomicBoolean; |
43 import java.util.concurrent.atomic.AtomicInteger; |
46 import java.util.concurrent.atomic.AtomicInteger; |
44 |
47 |
45 import junit.framework.Test; |
48 import junit.framework.Test; |
484 barrier.reset(); |
487 barrier.reset(); |
485 assertFalse(barrier.isBroken()); |
488 assertFalse(barrier.isBroken()); |
486 assertEquals(0, barrier.getNumberWaiting()); |
489 assertEquals(0, barrier.getNumberWaiting()); |
487 } |
490 } |
488 } |
491 } |
|
492 |
|
493 /** |
|
494 * There can be more threads calling await() than parties, as long as each |
|
495 * task only calls await once and the task count is a multiple of parties. |
|
496 */ |
|
497 public void testMoreTasksThanParties() throws Exception { |
|
498 final ThreadLocalRandom rnd = ThreadLocalRandom.current(); |
|
499 final int parties = rnd.nextInt(1, 5); |
|
500 final int nTasks = rnd.nextInt(1, 5) * parties; |
|
501 final AtomicInteger tripCount = new AtomicInteger(0); |
|
502 final AtomicInteger awaitCount = new AtomicInteger(0); |
|
503 final CyclicBarrier barrier = |
|
504 new CyclicBarrier(parties, () -> tripCount.getAndIncrement()); |
|
505 final ExecutorService e = Executors.newFixedThreadPool(nTasks); |
|
506 final Runnable awaiter = () -> { |
|
507 try { |
|
508 if (ThreadLocalRandom.current().nextBoolean()) |
|
509 barrier.await(); |
|
510 else |
|
511 barrier.await(LONG_DELAY_MS, MILLISECONDS); |
|
512 awaitCount.getAndIncrement(); |
|
513 } catch (Throwable fail) { threadUnexpectedException(fail); }}; |
|
514 try (PoolCleaner cleaner = cleaner(e)) { |
|
515 for (int i = nTasks; i--> 0; ) |
|
516 e.execute(awaiter); |
|
517 } |
|
518 assertEquals(nTasks / parties, tripCount.get()); |
|
519 assertEquals(nTasks, awaitCount.get()); |
|
520 assertEquals(0, barrier.getNumberWaiting()); |
|
521 } |
489 } |
522 } |