Метод класса java.util.concurrent.CyclicBarrier getNumberWaiting (), возвращающий случайный вывод - PullRequest
0 голосов
/ 14 января 2019

У меня есть пример использования java.util.concurrent.CyclicBarrier, который использует метод getNumberWaiting() для получения числа ожидающих сторон. Этот метод дает случайные результаты, иногда он говорит 0, а иногда говорит 1, что, кажется, не правильно.

package sample;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierTest {

    public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
        // TODO Auto-generated method stub
        CyclicBarrier barrier = new CyclicBarrier(2);

        MyService service_1 = new MyService(barrier, "Service-1");
        MyService service_2 = new MyService(barrier, "Service-2");
        Thread t1 = new Thread(service_1);
        Thread t2 = new Thread(service_2);
        t1.start();
        t2.start();

    }
}

class MyService implements Runnable {

    private CyclicBarrier barrier;

    private String name;

    public MyService(CyclicBarrier barrier, String name) {
        super();
        this.barrier = barrier;
        this.name = name;
    }

    public void run() {
        System.out.println("Starting Service : " + name);
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("Service " + name + " : started");
        try {

            System.out.println("Parties waiting at barrier " + barrier.getNumberWaiting() + " parties");

            barrier.await();
            System.out.println("Breaking barrier for service : " + name);

        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("Successfully done");
    }
}

Фактический результат: -
Запуск сервиса: Сервис-2
Запуск сервиса: Сервис-1
Сервис Сервис-1: запущен
Сервис Сервис-2: запущен
Вечеринки, ожидающие у барьера 0 вечеринок
Вечеринки, ожидающие у барьера 0 вечеринок
Преодолевая барьер на службе: Сервис-2
Успешно сделано
Преодолевая барьер на службе: Сервис-1
Успешно сделано

Ожидаемый результат: -
Запуск сервиса: Сервис-2
Запуск сервиса: Сервис-1
Сервис Сервис-1: запущен
Сервис Сервис-2: запущен
Вечеринки, ожидающие у барьера 0 вечеринок
Вечеринки в ожидании барьера 1 вечеринки
Преодолевая барьер на службе: Сервис-2
Успешно сделано
Преодолевая барьер на службе: Сервис-1
Успешно сделано

Ответы [ 2 ]

0 голосов
/ 15 января 2019

Поскольку оба потока идентичны (включая значение спящего режима), вы рискуете перемежаться между двумя потоками в местах, которые вы можете не ожидать. В этом случае после Parties waiting at barrier....

Если случится, что оба потока завершили этот вывод и не запустили свои await(), появится число 0.

Наличие разных значений sleep() для каждого потока увеличит шансы того, что они не будут перемежаться таким образом, если вы намерены просто проверить функциональность CyclicBarrier.

0 голосов
/ 14 января 2019

Вы ожидаете этот порядок исполнения:

  1. Тема 1 `System.out.println (" Стороны, ожидающие у барьера ...
  2. Тема 1 барьер.await ();
  3. Тема 2 `System.out.println (" Стороны, ожидающие у барьера ...
  4. Тема 2 барьер.await ();

Однако это не гарантируется, это может быть:

  1. Тема 1 `System.out.println (" Стороны, ожидающие у барьера ...
  2. Тема 2 `System.out.println (" Стороны, ожидающие у барьера ...
  3. Тема 1 барьер.await ();
  4. Тема 2 барьер.await ();
...