正在寻找适合此问题的同步 java 代码

Looking for an Appropriate synchronization java code for this problem

问题

乘客来到公交车站等车。当公共汽车到达时,所有等候的乘客调用 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 && !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();
    }
}

线程不是 运行,因为我期望输出是

这个问题是并发编程中的常见问题。 Grant Hutchins 对这个问题做了一个绝妙的解决方案。 他使用了 3 个信号量和一个计数器来得到一个解决方案

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

waiting - 上车区的乘客人数。

mutex - 用于保护等待变量。

bus - 用于告诉骑手巴士是否在场。

boarded - 告诉公交车乘客已经上车了

总线进程代码

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人,waiting将设置为零,否则我们减少50位乘客,因为50位乘客上车。

然后我们释放互斥锁,以便新骑手可以来增加价值。

车手代码

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

rider thread 在获取锁时等待互斥锁,它会增加等待以告知它正在等待总线。

乘客线程正在等待公交车,所以当公交车到达时,乘客线程可以转到 board 方法。然后骑手执行 board() 方法,它将发出骑手已登机的信号。所以巴士会再次发出信号以登上另一个线程。

我们还有另一种解决方案,在这个book中有描述。 Java 实现可以在这个 github link

中找到

`