A CyclicBarrier generation breaks when a waiting party times out, and later await calls fail until the barrier is reset or replaced.
Java CyclicBarrier timeout: a broken generation needs a recovery rule
Treat timeout as group failure
A phase cannot be considered complete when one participant abandons the rendezvous. The fixture uses a zero-timeout wait with two required parties, then verifies that the barrier is broken and that a later await reports the broken state. Reset creates a new generation; it does not finish the abandoned work.
CountDownLatch is one-shot and does not have the same generation model. Phaser registration is useful when party membership can change, but it also needs a failure policy.
Do not hide failed work with reset
Reset only after every participant has agreed how to discard or retry the old phase. A caller that simply resets and continues can mix outputs from two generations. Bound waits and retain enough phase identity to reject late results.
Working program
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class BatchPhaseRecovery {
public static void main(String[] args) throws InterruptedException {
CyclicBarrier phase = new CyclicBarrier(2);
try { phase.await(0, TimeUnit.NANOSECONDS); }
catch (TimeoutException expired) { System.out.println("phase timed out"); }
catch (BrokenBarrierException unexpected) { throw new AssertionError(unexpected); }
System.out.println("broken=" + phase.isBroken());
try { phase.await(); }
catch (BrokenBarrierException rejected) { System.out.println("old phase rejected"); }
phase.reset();
System.out.println("broken=" + phase.isBroken());
}
}Output
phase timed out
broken=true
old phase rejected
broken=falseCost and ownership
The demonstration uses constant memory. Real phases incur synchronization and waiting costs for all parties; a timeout does not reclaim unfinished tasks. Recovery must account for those tasks before a new generation begins.
Common Mistakes
- Do not treat reset as completion of the failed phase.
- Do not let an unbounded await hold a worker forever without a failure policy.
- Do not merge late results from a broken generation into the next one.
Read next
Java CountDownLatch: completion counting does not count successful work, Java Phaser: deregister workers so a phase can complete, Java cancellation: timed waits and cooperative interruption, Java conditions: protected predicates and timed waiting.
