Что такое Phaser в Java и чем он отличается от CountDownLatch и CyclicBarrier?

«Что такое Phaser в Java и чем он отличается от CountDownLatch и CyclicBarrier?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Phaser — это класс из java.util.concurrent для синхронизации потоков, который объединяет и расширяет возможности CountDownLatch и CyclicBarrier. Его ключевая особенность — динамическое количество участников и многофазная синхронизация.

Основные методы:

  • register() — добавляет нового участника.
  • arriveAndAwaitAdvance() — поток сообщает о прибытии на текущую фазу и блокируется, пока все зарегистрированные потоки не сделают то же самое.
  • arriveAndDeregister() — поток прибывает и уменьшает количество участников для следующих фаз.

Пример использования:

// Создаем Phaser с 1 участником (главный поток)
Phaser phaser = new Phaser(1); 

for (int i = 0; i < 3; i++) {
    phaser.register(); // Регистрируем новый поток-участник
    new Thread(() -> {
        System.out.println("Поток " + Thread.currentThread().getId() + " начал фазу " + phaser.getPhase());
        phaser.arriveAndAwaitAdvance(); // Ждем всех на этой фазе

        System.out.println("Поток " + Thread.currentThread().getId() + " начал фазу " + phaser.getPhase());
        phaser.arriveAndDeregister(); // Завершаем участие после второй фазы
    }).start();
}
phaser.arriveAndDeregister(); // Главный поток запускает первую фазу
Сравнение с другими синхронизаторами: Синхронизатор Фиксированное кол-во Много фаз Динамическое кол-во
CountDownLatch Да Нет (одноразовый) Нет
CyclicBarrier Да Да Нет
Phaser Нет Да Да

Применение: Сложные многоэтапные задачи (например, симуляции, поэтапная обработка данных), где количество рабочих потоков может меняться в процессе выполнения.