[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-mnogopotochnost-chto-takoe-phaser-i-kogda-ego-ispolzovat":3},{"id":4,"slug":5,"topicId":6,"topicSlug":7,"topicName":8,"topicEmoji":9,"question":10,"answer":11,"codeLang":12,"codeSrc":12,"important":12,"commonMistakes":12,"modernUsage":12,"difficulty":13,"tags":14,"related":21,"progress":22,"seo":23},301,"chto-takoe-phaser-i-kogda-ego-ispolzovat",8,"mnogopotochnost","Многопоточность","🔀","Что такое Phaser и когда его использовать?","\u003C!-- grade: 5\u002F5 — подробный ответ с примерами и сравнением -->\n\n`Phaser` — это синхронизатор из `java.util.concurrent` (Java 7), который объединяет функциональность `CountDownLatch` и `CyclicBarrier` и дополняет их **динамическим управлением количеством участников** и поддержкой **нескольких фаз**.\n\n**Основные концепции:**\n- **Фаза (phase)** — текущий этап синхронизации. Номер начинается с 0.\n- **Участник (party)** — зарегистрированный поток. Количество можно изменять динамически.\n- **Прибытие (arrive)** — сигнал от участника о завершении текущей фазы.\n\n\u003Cdetails>\n\u003Csummary>Код: три потока, три фазы обработки\u003C\u002Fsummary>\n\n```java\nPhaser phaser = new Phaser(3); \u002F\u002F 3 участника\n\nfor (int i = 0; i \u003C 3; i++) {\n    final int threadId = i;\n    new Thread(() -> {\n        \u002F\u002F Фаза 0: Загрузка данных\n        System.out.println(\"Поток \" + threadId + \": загрузка данных\");\n        phaser.arriveAndAwaitAdvance(); \u002F\u002F Ждём, пока все загрузят данные\n\n        \u002F\u002F Фаза 1: Обработка данных\n        System.out.println(\"Поток \" + threadId + \": обработка данных\");\n        phaser.arriveAndAwaitAdvance();\n\n        \u002F\u002F Фаза 2: Сохранение результатов\n        System.out.println(\"Поток \" + threadId + \": сохранение результатов\");\n        phaser.arriveAndDeregister(); \u002F\u002F Завершаем участие\n    }).start();\n}\n```\n\n\u003C\u002Fdetails>\n\n**Динамическое управление участниками:**\n\n```java\nPhaser phaser = new Phaser(1); \u002F\u002F Главный поток — 1 участник\n\nfor (int i = 0; i \u003C 5; i++) {\n    phaser.register(); \u002F\u002F Регистрируем нового участника\n    new Thread(() -> {\n        try {\n            doWork();\n        } finally {\n            phaser.arriveAndDeregister();\n        }\n    }).start();\n}\n\nphaser.arriveAndAwaitAdvance(); \u002F\u002F Главный поток ждёт завершения всех\n```\n\n**Переопределение `onAdvance` для управления фазами:**\n\n```java\nPhaser phaser = new Phaser(3) {\n    @Override\n    protected boolean onAdvance(int phase, int registeredParties) {\n        System.out.println(\"Фаза \" + phase + \" завершена. Участников: \" + registeredParties);\n        return phase >= 2 || registeredParties == 0; \u002F\u002F Завершить после 3 фаз\n    }\n};\n```\n\n**Сравнение синхронизаторов:**\n\n| Характеристика | `CountDownLatch` | `CyclicBarrier` | `Phaser` |\n|---|---|---|---|\n| Повторное использование | Нет | Да | Да |\n| Динамическое число участников | Нет | Нет | Да |\n| Несколько фаз | Нет | Да (одинаковые) | Да (разные) |\n| Иерархическая структура | Нет | Нет | Да (tiered phaser) |\n\n**Основные методы:**\n- `arriveAndAwaitAdvance()` — «я прибыл и жду остальных».\n- `arrive()` — «я прибыл, но не жду» (неблокирующий).\n- `arriveAndDeregister()` — «я прибыл и выхожу из игры».\n- `register()` — добавить нового участника.\n\n**Частые ошибки:**\n- Забытая дерегистрация — остальные потоки зависнут.\n- Использование для простых сценариев — `CountDownLatch` проще.\n- Начальное число участников 0 — `Phaser` считается завершённым.\n\n> **Аналогия:** `Phaser` — это многодневный поход. Группа (участники) проходит маршрут поэтапно (фазы). На каждом привале (барьер) все ждут друг друга. Кто-то может присоединиться по дороге (register), кто-то — сойти (deregister). Руководитель (onAdvance) решает, продолжать ли путь.\n\n> **На собеседовании** ключевой вопрос: «Когда `Phaser` лучше `CyclicBarrier`?» Ответ: когда число участников меняется динамически или нужна иерархическая структура (tiered phasers) для масштабирования.","","senior",[15,16,17,18,19,20],"фазы","синхронизатор","барьер","Phaser","динамические-участники","concurrency",[],null,{"title":24,"description":25,"ogTitle":26,"ogDescription":27,"keywords":28,"schemaAnswer":34,"featuredSnippetReady":35},"Phaser в Java — многофазный синхронизатор с динамическими участниками — Gymterview","Phaser (Java 7) объединяет CountDownLatch и CyclicBarrier: несколько фаз, динамическое число участников, иерархическая структура. Примеры использования.","Phaser — динамический многофазный барьер в Java","Phaser поддерживает несколько фаз синхронизации с динамическим числом участников. Комбинирует CountDownLatch и CyclicBarrier.",[29,30,31,32,33],"Phaser Java","многофазная синхронизация","arriveAndAwaitAdvance","динамические участники","Phaser vs CyclicBarrier","Phaser (Java 7) — синхронизатор, объединяющий CountDownLatch и CyclicBarrier. Поддерживает несколько фаз (этапов), динамическое добавление\u002Fудаление участников (register\u002FarriveAndDeregister), иерархическую структуру (tiered phasers). Метод arriveAndAwaitAdvance() — основной: «я завершил фазу и жду остальных». Переопределение onAdvance() управляет количеством фаз. Используется в ETL, map-reduce, игровых серверах.",true]