< 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,10 +35,11 @@
 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,41 +292,46 @@
 
     /**
      * Handling of extra interrupts while waiting - tests for bug 6366811
      */
     private static void testInterrupts() {
-        final int N = 10;
+        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 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;
+            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;
             }
-            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; }
+                    else barrier.await();
+                } catch (Throwable throwable) {
+                    this.throwable = throwable;
+                }
 
-                try { doneSignal.await(LONG_DELAY_MS, MILLISECONDS); }
-                catch (InterruptedException e) { interrupted = true; }
+                try {
+                    check(doneSignal.await(LONG_DELAY_MS, MILLISECONDS));
+                    if (Thread.interrupted())
+                        interruptStatusSetAfterAwait = true;
+                } catch (InterruptedException e) {
+                    interruptStatusSetAfterAwait = true;
+                }
             }
         }
 
         //----------------------------------------------------------------
         // Interrupt occurs during barrier trip

@@ -350,28 +356,26 @@
                     // 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 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 countInterrupted = 0;
-            int countInterruptedException = 0;
-            int countBrokenBarrierException = 0;
+            int countInterruptStatusSetAfterAwait = 0;
             for (Waiter waiter : waiters) {
                 waiter.join();
-                equal(waiter.throwable(), null);
-                if (waiter.interruptBit())
-                    countInterrupted++;
+                equal(waiter.throwable, null);
+                if (waiter.interruptStatusSetAfterAwait)
+                    countInterruptStatusSetAfterAwait++;
             }
-            equal(countInterrupted, N/2);
+            equal(countInterruptStatusSetAfterAwait, N/2);
             check(! barrier.isBroken());
         } catch (Throwable t) { unexpected(t); }
 
         //----------------------------------------------------------------
         // Multiple interrupts occur during barrier await

@@ -379,35 +383,37 @@
         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 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++)
-                waiters.get(i).interrupt();
+            for (int i = 0; i < N/2; i++) {
+                Thread waiter = waiters.get(i);
+                waiter.interrupt();
+            }
             doneSignal.countDown();
-            int countInterrupted = 0;
             int countInterruptedException = 0;
             int countBrokenBarrierException = 0;
+            int countInterruptStatusSetAfterAwait = 0;
             for (Waiter waiter : waiters) {
                 waiter.join();
-                if (waiter.throwable() instanceof InterruptedException)
+                if (waiter.throwable instanceof InterruptedException)
                     countInterruptedException++;
-                if (waiter.throwable() instanceof BrokenBarrierException)
+                if (waiter.throwable instanceof BrokenBarrierException)
                     countBrokenBarrierException++;
-                if (waiter.interruptBit())
-                    countInterrupted++;
+                if (waiter.interruptStatusSetAfterAwait)
+                    countInterruptStatusSetAfterAwait++;
             }
-            equal(countInterrupted, N/2-1);
             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 >