< prev index next >
test/jdk/java/util/concurrent/CyclicBarrier/Basic.java
Print this page
8145138: CyclicBarrier/Basic.java failed with "3 not equal to 4"
Reviewed-by: martin, alanb
*** 35,44 ****
--- 35,45 ----
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
+ import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
import jdk.test.lib.Utils;
public class Basic {
*** 291,331 ****
/**
* Handling of extra interrupts while waiting - tests for bug 6366811
*/
private static void testInterrupts() {
! final int N = 10;
final CyclicBarrier startingGate = new CyclicBarrier(N+1);
/**
* A version of Awaiter that also records interrupted state.
*/
class Waiter extends CheckedThread {
! private boolean timed;
! private CyclicBarrier barrier;
! private CountDownLatch doneSignal;
! private Throwable throwable;
! private boolean interrupted;
!
! public Waiter(boolean timed,
! CountDownLatch doneSignal,
! CyclicBarrier barrier) {
! this.timed = timed;
this.doneSignal = doneSignal;
this.barrier = barrier;
}
! Throwable throwable() { return this.throwable; }
! boolean interruptBit() { return this.interrupted; }
void realRun() throws Throwable {
startingGate.await(LONG_DELAY_MS, MILLISECONDS);
try {
if (timed) barrier.await(LONG_DELAY_MS, MILLISECONDS);
! else barrier.await(); }
! catch (Throwable throwable) { this.throwable = throwable; }
! try { doneSignal.await(LONG_DELAY_MS, MILLISECONDS); }
! catch (InterruptedException e) { interrupted = true; }
}
}
//----------------------------------------------------------------
// Interrupt occurs during barrier trip
--- 292,337 ----
/**
* Handling of extra interrupts while waiting - tests for bug 6366811
*/
private static void testInterrupts() {
! final int N = ThreadLocalRandom.current().nextInt(2, 10);
final CyclicBarrier startingGate = new CyclicBarrier(N+1);
/**
* A version of Awaiter that also records interrupted state.
*/
class Waiter extends CheckedThread {
! private final boolean timed;
! private final CyclicBarrier barrier;
! private final CountDownLatch doneSignal;
! volatile Throwable throwable;
! volatile boolean interruptStatusSetAfterAwait;
!
! public Waiter(CountDownLatch doneSignal, CyclicBarrier barrier) {
! this.timed = ThreadLocalRandom.current().nextBoolean();
this.doneSignal = doneSignal;
this.barrier = barrier;
}
!
void realRun() throws Throwable {
startingGate.await(LONG_DELAY_MS, MILLISECONDS);
+
try {
if (timed) barrier.await(LONG_DELAY_MS, MILLISECONDS);
! else barrier.await();
! } catch (Throwable throwable) {
! this.throwable = throwable;
! }
! try {
! check(doneSignal.await(LONG_DELAY_MS, MILLISECONDS));
! if (Thread.interrupted())
! interruptStatusSetAfterAwait = true;
! } catch (InterruptedException e) {
! interruptStatusSetAfterAwait = true;
! }
}
}
//----------------------------------------------------------------
// Interrupt occurs during barrier trip
*** 350,377 ****
// seems to work reliably while yield does not.
Thread.sleep(100);
} catch (Throwable t) { unexpected(t); }
}};
for (int i = 0; i < N; i++) {
! Waiter waiter = new Waiter(i < N/2, doneSignal, barrier);
waiter.start();
waiters.add(waiter);
}
startingGate.await(LONG_DELAY_MS, MILLISECONDS);
while (barrier.getNumberWaiting() < N) Thread.yield();
barrier.await();
doneSignal.countDown();
! int countInterrupted = 0;
! int countInterruptedException = 0;
! int countBrokenBarrierException = 0;
for (Waiter waiter : waiters) {
waiter.join();
! equal(waiter.throwable(), null);
! if (waiter.interruptBit())
! countInterrupted++;
}
! equal(countInterrupted, N/2);
check(! barrier.isBroken());
} catch (Throwable t) { unexpected(t); }
//----------------------------------------------------------------
// Multiple interrupts occur during barrier await
--- 356,381 ----
// seems to work reliably while yield does not.
Thread.sleep(100);
} catch (Throwable t) { unexpected(t); }
}};
for (int i = 0; i < N; i++) {
! Waiter waiter = new Waiter(doneSignal, barrier);
waiter.start();
waiters.add(waiter);
}
startingGate.await(LONG_DELAY_MS, MILLISECONDS);
while (barrier.getNumberWaiting() < N) Thread.yield();
barrier.await();
doneSignal.countDown();
! int countInterruptStatusSetAfterAwait = 0;
for (Waiter waiter : waiters) {
waiter.join();
! equal(waiter.throwable, null);
! if (waiter.interruptStatusSetAfterAwait)
! countInterruptStatusSetAfterAwait++;
}
! equal(countInterruptStatusSetAfterAwait, N/2);
check(! barrier.isBroken());
} catch (Throwable t) { unexpected(t); }
//----------------------------------------------------------------
// Multiple interrupts occur during barrier await
*** 379,413 ****
try {
final CountDownLatch doneSignal = new CountDownLatch(1);
final CyclicBarrier barrier = new CyclicBarrier(N+1);
final List<Waiter> waiters = new ArrayList<>(N);
for (int i = 0; i < N; i++) {
! Waiter waiter = new Waiter(i < N/2, doneSignal, barrier);
waiter.start();
waiters.add(waiter);
}
startingGate.await(LONG_DELAY_MS, MILLISECONDS);
while (barrier.getNumberWaiting() < N) Thread.yield();
! for (int i = 0; i < N/2; i++)
! waiters.get(i).interrupt();
doneSignal.countDown();
- int countInterrupted = 0;
int countInterruptedException = 0;
int countBrokenBarrierException = 0;
for (Waiter waiter : waiters) {
waiter.join();
! if (waiter.throwable() instanceof InterruptedException)
countInterruptedException++;
! if (waiter.throwable() instanceof BrokenBarrierException)
countBrokenBarrierException++;
! if (waiter.interruptBit())
! countInterrupted++;
}
- equal(countInterrupted, N/2-1);
equal(countInterruptedException, 1);
equal(countBrokenBarrierException, N-1);
checkBroken(barrier);
reset(barrier);
} catch (Throwable t) { unexpected(t); }
}
//--------------------- Infrastructure ---------------------------
--- 383,419 ----
try {
final CountDownLatch doneSignal = new CountDownLatch(1);
final CyclicBarrier barrier = new CyclicBarrier(N+1);
final List<Waiter> waiters = new ArrayList<>(N);
for (int i = 0; i < N; i++) {
! Waiter waiter = new Waiter(doneSignal, barrier);
waiter.start();
waiters.add(waiter);
}
startingGate.await(LONG_DELAY_MS, MILLISECONDS);
while (barrier.getNumberWaiting() < N) Thread.yield();
! for (int i = 0; i < N/2; i++) {
! Thread waiter = waiters.get(i);
! waiter.interrupt();
! }
doneSignal.countDown();
int countInterruptedException = 0;
int countBrokenBarrierException = 0;
+ int countInterruptStatusSetAfterAwait = 0;
for (Waiter waiter : waiters) {
waiter.join();
! if (waiter.throwable instanceof InterruptedException)
countInterruptedException++;
! if (waiter.throwable instanceof BrokenBarrierException)
countBrokenBarrierException++;
! if (waiter.interruptStatusSetAfterAwait)
! countInterruptStatusSetAfterAwait++;
}
equal(countInterruptedException, 1);
equal(countBrokenBarrierException, N-1);
checkBroken(barrier);
+ equal(countInterruptStatusSetAfterAwait, N/2-1);
reset(barrier);
} catch (Throwable t) { unexpected(t); }
}
//--------------------- Infrastructure ---------------------------
< prev index next >