我一直在学习Java的并发性,并且遇到了生产者-消费者问题。这显然是标准的,而且我在很多地方都看到了几乎相同的答案。

public synchronized void put(int num){
    while (!empty) {
        try{
            wait(); }
        catch {}
    }

    buffer=num;
    empty=false;
    notify();
}

public synchronized int take(){
    while (empty) {
        try{
            wait(); }
        catch {}
    }

    empty=true;
    notify();
    return buffer;
}

我对sync的理解是,它使用了对象范围的锁,这意味着线程不能同时放入和取出。但是,这两种方法都在等待另一种方法。这就是我感到困惑的地方:这似乎会造成死锁。如果线程A放入put while empty=false,它将等待。但是,线程B无法同步,因此无法输入take。因此,空将永远是假的,从而导致死锁。

考虑到我已经基本看过这个答案多少次了,看来它一定是正确的。我理解错了什么?

谢谢!

最佳答案

调用wait将释放进入方法时获得的锁。因此,如果A输入了put并称为wait,则锁定被释放,然后B可以在take内部进行操作。

javadoc:

The current thread must own this object's monitor. The thread releases ownership
of this monitor and waits until another thread notifies threads waiting on this
object's monitor to wake up either through a call to the notify method or the
notifyAll method. The thread then waits until it can re-obtain ownership of the
monitor and resumes execution.

09-26 18:04