我一直试图解决这个问题两天了,我终于放弃了,我在这里发布我的代码,希望有些人可以为我提供我一直缺少的东西,因为我认为我是关闭,请帮忙!
理发师代码:
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;
答案 0 :(得分:0)
Semaphore
是一个计数信号量 - 您应该阅读javadoc以获取更多信息。问题是,您永远不会告诉barber
Semaphore
有可用的Barber
。所以永远不会允许Customer
获得它。
解决方案:
当您创建Barber
时,您要做的第一件事就是调用barber.release()
(在while循环之前!)或用{1}初始化barber
。
答案 1 :(得分:0)
这不是一个正确的答案,但有几件事情在这里看起来不对:
1)freeChairs应该是AtomicInteger。
2)看起来你在错误的块中设置notCut = false - 肯定应该在getHaircut()之后设置? (尝试命名布尔'cut'并将其初始化为false。双阴性使得人类更难处理!)
3)很多信号量的获取和释放应该是相对于彼此的原子,但不是。例如
barber.release();
accessSeats.release();
看起来它应该是原子的 - 另一个线程应该永远不能看到已经释放理发信号量的状态但是accessSeats没有,但这不是这里的情况。这可能导致死锁,除非你非常小心你在不同的信号量上调用aquire / release的命令。