Search⌘ K
AI Features

BrokenBarrierException

Explore the causes and scenarios of BrokenBarrierException in Java concurrency. Understand how thread interruptions and broken barriers trigger this exception, especially when using CyclicBarrier in multithreaded environments.

We'll cover the following...

If you are interviewing, consider buying our number#1 course for Java Multithreading Interviews.

Overview

The BrokenBarrierException is usually an indication of a programming flaw. It occurs when:

  1. A thread is already waiting on a barrier and the barrier enters the broken state.
  2. A thread attempts to wait on a barrier that is in the broken state.

Example

Consider the program below that submits two tasks to the executor. Both the tasks await() on a CyclicBarrier object, which is initialized with a count of 3, i.e. three threads must await() the barrier object before they can proceed forward. The main thread cancel()-s one of the tasks. The thread executing the task is already waiting on the barrier and experiences an InterruptedException. At this point the barrier is broken and the second task throws BrokenBarrierException. This sequence of events manifests the first condition described above i.e. BrokenBarrierException is thrown when a barrier is broken and there are threads already waiting on the barrier object.

The other condition when a BrokenBarrierException is thrown, is when a thread attempts to await() an already broken barrier. This is showcased by the main thread when it await()-s the broken barrier object on line#55 and the program exits with the BrokenBarrierException.

Java
import java.util.concurrent.*;
class Demonstration {
public static void main( String args[] ) throws InterruptedException, BrokenBarrierException {
CyclicBarrier barrier = new CyclicBarrier(3);
ExecutorService executorService = Executors.newFixedThreadPool(5);
Runnable task1 = new Runnable() {
@Override
public void run() {
try {
barrier.await();
} catch (BrokenBarrierException bbe) {
System.out.println("Broken barrier exception experienced by " + Thread.currentThread().getName());
} catch (InterruptedException ie) {
System.out.println("Interrupted exception experienced by " + Thread.currentThread().getName());
}
}
};
Runnable task2 = new Runnable() {
@Override
public void run() {
try {
barrier.await();
} catch (BrokenBarrierException bbe) {
System.out.println("Broken barrier exception experienced by " + Thread.currentThread().getName());
} catch (InterruptedException ie) {
System.out.println("Interrupted exception experienced by " + Thread.currentThread().getName());
}
}
};
try {
Future future1 = executorService.submit(task1);
executorService.submit(task2);
// wait for other threads to reach the barrier. Never use Thread.sleep() for synchronization among
// threads. This example uses it only for demonstration purposes.
Thread.sleep(1000);
// cancel the first task so that the thread executing it is interrupted while waiting on the barrier
future1.cancel(true);
// wait for both other threads to finish.
Thread.sleep(1000);
// check the state of the barrier
System.out.println("Is barrier broken " + barrier.isBroken());
// attempt to wait on an already broken barrier
barrier.await();
} finally {
// remember to shut down the executor
executorService.shutdown();
}
}
}