我一直在玩实现自己非常基本的信号量,并注意到我选择的实现会影响我是否会遇到死锁。但我不明白僵局是如何发生的。
我原来的实现(没有死锁):
public synchronized void waitFor(){
value--;
if(value < 0)
wait();
}
public synchronized void signal(){
value++;
notify();
}
稍后的实现(导致死锁):
public synchronized void waitFor(){
value--;
while(value < 0)
wait();
}
public synchronized void signal(){
value++;
notifyAll();
}
在两组用于捕获线程中断的代码中,wait()实际上都被try-catch所包围,但为了便于阅读,我把它留了下来,并假设它对死锁问题没有任何影响。
有人有什么想法吗?
答案 0 :(得分:0)
我无法发现第二次实施的任何死锁风险。 while循环是等待锁定的正确选择(参见Object.wait() documentation中的虚假唤醒)。
此外,看起来不会错过任何信号操作。只有当另一个线程处于等待状态,或没有其他线程正在运行时才会发生信号waitFor()。
因此,我建议您检查代码的其他部分:
答案 1 :(得分:-1)
正在使用
while(value < 0)
wait();
在后一个实现中,它位于值<0的非结束循环中,并且它永远在这里循环。
这可能是你死锁情况的指针。