Поиск подходящего кода синхронизации java для этой проблемы

#java #multithreading #concurrency #mutex #semaphore

#java #многопоточность #параллелизм #мьютекс #семафор

Вопрос:

Проблема

Пассажиры приходят на автобусную остановку и ждут автобус. Когда прибывает автобус, все ожидающие пассажиры вызывают boardBus, но любой, кто прибывает во время посадки в автобус, должен ждать следующего автобуса. Вместимость автобуса составляет 50 человек; если в ожидании более 50 человек, некоторым придется ждать следующего автобуса. Когда все ожидающие пассажиры сели, автобус может вызвать отправку. Если автобус прибывает, когда нет пассажиров, он должен немедленно отправляться. Обратите внимание, что автобусы и пассажиры будут продолжать прибывать в течение дня. Предположим, что время прибытия автобусов и пассажиров распределяется экспоненциально со средним значением 20 минут и 30 секунд соответственно.

Для этой проблемы мне нужна параллельная программа, которая может удовлетворять взаимному исключению и синхронизации на Java с четким объяснением. Кто-нибудь может мне помочь?

Шина

 public class Bus {

    public Bus() {
    }

    public void depart() {
        System.out.println("I am departuring from the busstand....");
    }
}
  

Наездник

 import java.util.ArrayList;
import java.util.concurrent.Semaphore;

public class Rider{

    public void invokeBoard() {
        System.out.println("I am boarding to the .... in the bus");
    }
}
  

Диспетчер шинных станций

 import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class BusStandManager {
    boolean isArrived;
    int n;
    Semaphore count_mutex;
    Semaphore bus_mutex;
    ArrayList<Rider> waiting_stage_queue;
    ArrayList<Rider> bus_stand_queue;

    public BusStandManager() {

        this.isArrived = false;
        this.n = 0;
        this.count_mutex = new Semaphore(1);
        this.bus_mutex = new Semaphore(1);
        this.waiting_stage_queue = new ArrayList<>();
        this.bus_stand_queue = new ArrayList<>();
    }

    public void putRider() {
        Rider rider = new Rider();
        try {
            count_mutex.acquire();
            if (n < 50 amp;amp; !isArrived) {
                n = n   1;
                bus_stand_queue.add(rider);
            } else {
                waiting_stage_queue.add(rider);
            }
            count_mutex.release();
        } catch (InterruptedException e) {
            System.out.println("Thread is suspended");
        }
    }

    public void load_bus()  {
        try{
        bus_mutex.acquire();
        Bus bus = new Bus();
        isArrived = true;
        if (n != 0) {
            for (Rider rider : bus_stand_queue) {
                rider.invokeBoard();
            }
            n = 0;
        }
        bus.depart();}
        catch (InterruptedException ie){
            System.out.println("Thread is suspended");

        }
    }

    public void execute() {
        ExecutorService executorService = Executors.newFixedThreadPool(10);

        // method reference introduced in Java 8
        executorService.submit(this::putRider);
        executorService.submit(this::load_bus);

        // close executorService
        executorService.shutdown();
    }
}
  

Использование

 public class Main {

    public static void main(String[] args) {
        BusStandManager busStandManager = new BusStandManager();
        busStandManager.execute();
    }
}

  

Поток не выполняется, поскольку я ожидаю, что результат
вывод

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

1. Ну, что вы пробовали?

2. Нет, мы не будем делать вашу домашнюю работу за вас. Покажите нам, что вы пробовали, и объясните, где вы застряли, и мы сможем помочь вам с вашей проблемой

3. Привет @Anix, пожалуйста, проверьте мое обновление

4. Посмотрите на мой ответ

Ответ №1:

Эта проблема является распространенной проблемой в параллельном программировании. Грант Хатчинс сделал фантастическое решение этой проблемы. Он использовал 3 семафора и счетчик, чтобы получить решение

 waiting = 0;
mutex = new Semaphore(1)
bus = new Semaphore(0)
boarded = new Semaphore(0)
  

ожидание — количество пассажиров в зоне посадки.

мьютекс — используется для защиты ожидающей переменной.

bus — используется, чтобы сообщить гонщикам, что автобус в суде или нет.

boarded — используется для сообщения шине, что rider загружен.

Код процесса шины

 mutex . wait ()
n = min ( waiting , 50)
for i in range ( n ):
bus . signal ()
boarded . wait ()
waiting = max ( waiting -50 , 0)
mutex . signal ()
depart ()
  

Здесь мьютекс используется для блокировки переменной ожидания, поскольку всякий раз, когда приходит шина, никто не может увеличить ожидание.
n — это минимум ожидания и 50, поскольку, если у нас 70 гонщиков, мы можем посадить только 50 гонщиков на автобус, а если у нас 30 гонщиков, мы можем посадить всех гонщиков на автобус. При этом минимальном условии мы берем только 50 пассажиров в автобус.
Затем для каждого сигнала шины райдера, что он прибыл, чтобы райдер мог сесть в автобус.

После того, как в автобус будут загружены 50 гонщиков, ожидание будет установлено равным нулю, если на начальном этапе у нас меньше 50 гонщиков, в противном случае мы уменьшаем 50 от числа гонщиков, поскольку загружено 50 гонщиков.

затем мы освобождаем мьютекс, чтобы новый пользователь мог прийти и увеличить значение.

Код райдера

 mutex . wait ()
waiting  = 1
mutex . signal ()
bus . wait ()
board ()
boarded . signal ()

  

поток rider ожидает мьютекса, когда он получит блокировку, он увеличит ожидание, чтобы сообщить, что он ожидает шины.

Поток rider ожидает шину, поэтому, когда приходит шина, поток bus rider может перейти к методу board. затем rider выполняет метод board(), который будет сигнализировать о том, что rider загружен. таким образом, шина снова подаст сигнал на подключение к другому потоку.

У нас есть и другое решение, оно описано в этой книге. Реализацию Java можно найти по этой ссылке на github

`