Ответ
CyclicBarrier — это синхронизатор из пакета java.util.concurrent, который заставляет набор потоков ждать друг друга в определенной точке (барьере), прежде чем продолжить выполнение.
Ключевые характеристики:
- Цикличность: После того как ожидающие потоки достигнут барьера и будут освобождены, барьер сбрасывается и может быть использован повторно.
- Действие при достижении барьера: Можно задать
Runnable-задачу (барьерное действие), которая выполняется один раз после того, как последний поток достигнет барьера, но до того, как все потоки будут разблокированы.
Основные методы:
await(): Поток блокируется до достижения барьера заданным количеством потоков.await(long timeout, TimeUnit unit): То же, но с таймаутом.reset(): Принудительно сбрасывает барьер в исходное состояние, что приводит кBrokenBarrierExceptionв ожидающих потоках.
Пример: Три потока выполняют первую фазу работы, ждут друг друга, а затем начинают вторую фазу.
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierExample {
public static void main(String[] args) {
int threadCount = 3;
CyclicBarrier barrier = new CyclicBarrier(threadCount,
() -> System.out.println("--- Все потоки достигли барьера. Запускаем вторую фазу. ---"));
for (int i = 0; i < threadCount; i++) {
final int threadId = i;
new Thread(() -> {
try {
System.out.println("Поток " + threadId + " выполняет первую фазу.");
Thread.sleep((long) (Math.random() * 1000)); // Имитация работы
barrier.await(); // Ожидание других потоков
System.out.println("Поток " + threadId + " выполняет вторую фазу.");
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}
}
Отличие от CountDownLatch: CountDownLatch — одноразовый, потоки ждут события; CyclicBarrier — многоразовый, потоки ждут друг друга.