Страницы

Поиск по вопросам

четверг, 14 марта 2019 г.

Как работает java.util.concurrent.Phaser?

Как, в данном задании, Phaser понимает, что нити являются его участниками?
Вызвав метод arriveAndAwaitAdvance(), он присоединяет нить, в которой вызван, к пасеру в состоянии прибыла на барьер?
Phaser понимает, что нити являются его участниками, за счет методов arriveAndAwaitAdvance и arrive?
Без их вызова в данной задаче он будет пустой?
package com.javarush.test.level28.lesson10.home01;
import java.util.ArrayList; import java.util.List; import java.util.concurrent.Phaser;
public class Solution { public static void main(String[] args) throws InterruptedException { List characters = new ArrayList<>(); characters.add(new Plant()); characters.add(new Plant()); characters.add(new Zombie()); characters.add(new Zombie()); characters.add(new Zombie()); start(characters); }
private static boolean isEveryoneReady = false;
private static void start(List characters) throws InterruptedException { final Phaser phaser = new Phaser(1 + characters.size());
for (final Character character : characters) { final String member = character.toString(); System.out.println(member + " присоединился к игре");
new Thread() { @Override public void run() { System.out.println(member + " готовится играть"); phaser.arriveAndAwaitAdvance(); if (!isEveryoneReady) { isEveryoneReady = true; System.out.println("Игра началась!"); } character.run(); } }.start();
}
phaser.arriveAndDeregister(); } }


Ответ

Phaser -- это разновидность барьера, аналогичен CyclicBarrier и CountDownLatch, но отличается более гибкой настройкой.
Барьер в общем виде представляет собой следующее:
задается количество потоков, которое должно собраться на барьере каждый поток, прибывающий на барьер, блокируется как только на барьере собирается заданное выше количество потоков, барьер "открывается", и все потоки продолжают свою работу
Подробнее почитать про барьеры (в т.ч. про эти три реализации) и посмотреть иллюстрацию их работы можно в статье на Хабре
В приведенном коде Phaser работает так:
инициализируется значением участников 1 + characters.size() дальше потоки в количестве characters.size() регистрируются в нем и блокируются при вызове метода arriveAndDeregister() происходит регистрация последнего участника, барьер "открывается", все потоки продолжают свою работу. При этом этот метод автоматически уменьшает количество зарегистрированных участников для следующего этапа, но в данном коде это не имеет значения.

Отвечая на конкретные вопросы:
Вызвав метод arriveAndAwaitAdvance(), он присоединяет нить, в которой вызван, к пасеру в состоянии прибыла на барьер?
Да.
Phaser понимает, что нити являются его участниками, за счет методов arriveAndAwaitAdvance и arrive?
Да.
Без их вызова в данной задаче он будет пустой?
Не совсем понятно, что вы имеете в виду. Он будет "пустой" в том смысле, что счетчик зарегистрированных участников в нем будет равен нулю.

P.S. Кстати у вас есть проблема с полем isEveryoneReady -- доступ к нему не синхронизирован и вы можете получить несколько сообщений "Игра началась!".

Комментариев нет:

Отправить комментарий