2

我已经尝试解决这个问题两天了,我终于放弃了,我在这里发布我的代码,希望有人可以为我提供我所缺少的东西,因为我认为我很接近,请帮助!

理发师代码:

public Semaphore customer = new Semaphore(0);
public Semaphore barber = new Semaphore(0);
public Semaphore accessSeats = new Semaphore(1);
public int freeChairs = 5;

@Override
public void run() {
    while (true) {
        try {
            customer.acquire(); //it seems the barber never acuires a customer, even after the semaphore is released
            accessSeats.acquire();
            freeChairs += 1;
            cutHair();
            barber.release();
            accessSeats.release();
        } catch (InterruptedException ex){}

客户代码:

    public void run() {
    while (notCut) {
        try {
            bs.accessSeats.acquire();
        } catch (InterruptedException ex) {}
        if (bs.freeChairs > 0) {
            bs.freeChairs -= 1;
            bs.customer.release();
            bs.accessSeats.release();
            try {
                bs.barber.acquire(); //the customer cant get past this line
                getHaircut();
            } catch (InterruptedException ex) {}
        } else {
            bs.accessSeats.release();
            notCut = false;
        }
    }
}

我在随机计时器上创建了 1 个理发师和 100 个客户。

编辑:cutHair()让理发师线程休眠 1-5 秒(随机)。并getHaircut()打印一条消息,然后设置notCut=false;

4

2 回答 2

0

Semaphore是一个计数信号量 - 您应该阅读 javadoc 以获取更多信息。问题是你永远不会告诉barber Semaphore有一个可用的Barber. 所以它永远不会让 anCustomer获得它。

解决方案:当您创建一个Barber时,您要做的第一件事是调用barber.release()(在 while 循环之前!)或barber使用 1 许可进行初始化。

于 2013-05-24T10:58:33.573 回答
0

这不是一个正确的答案,但这里有几件事看起来不对:

1) freeChairs 应该是一个 AtomicInteger。

2) 看起来您在错误的块中设置了 notCut = false - 当然应该在 getHaircut() 之后设置?(尝试命名布尔值'cut'并将其初始化为false。双重否定使人类更难处理!)

3)许多信号量的获取和释放应该是原子的,但不是。例如

barber.release();
accessSeats.release();

看起来它应该是原子的——另一个线程应该永远无法看到理发信号量已被释放但 accessSeats 没有被释放的状态,但这里不是这种情况。这可能会导致死锁,除非您非常小心在不同信号量上调用 aquire / release 的顺序。

于 2013-05-24T11:00:49.643 回答