Страницы

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

четверг, 23 января 2020 г.

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

#java #concurrency


Как, в данном задании, 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();
    }
}

    


Ответы

Ответ 1



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

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

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