java:如果在锁定版本之前总是调用notify(),那么等待的线程如何获得同样的锁?

Dio*_*jos 9 java multithreading

我认为我已经知道了这个问题的答案,但是,我想阅读你的意见,以确保我真正理解java线程的状态机(或图表)是如何工作的.

想象一下,线程A 在返回给定值之前运行notify():

public class baz{

    // Thread B runs this:
    public synchronized void bar(){
       wait();
    } 

    // Thread A runs this:
    public synchronized int foo(){
       notify();
       return 11;
    }
}
Run Code Online (Sandbox Code Playgroud)

在线程A释放锁定之前将调用notify()(将在" 返回11 ;语句之后"发生).那么,等待这个锁(通过wait()方法)的线程B如何获得仍然由线程A保持的锁?请注意,当通知线程B时,线程A尚未释放锁定.

所以我对这种情况的看法如下:

在调用wait()之后,线程B将其状态从Running更改为Waiting.收到通知后(来自Thread A notify()方法),线程B将从wait()返回,将其状态更改为Runnable并尝试获取锁.由于线程A尚未释放锁定,因此线程B将在对象的监视器上被阻塞,并将其状态从Runnable传递到Blocked.最终,在线程A释放锁之后,线程B将获取锁并将其状态从阻塞传递到运行.

这是正确的吗?我想用这个问题理解的是从一个已经获得的锁同步的wait()返回的线程会发生什么.

Sot*_*lis 2

是的,你的解释是正确的。

当您调用wait()一个对象时,调用线程将被添加到该对象的等待集中。当它被notify()释放时,它将从该等待集中删除,并对对象执行锁定操作synchronized(它位于该对象的块内)。该锁定操作将阻塞当前线程,直到它完成,即。锁定对象监视器。

这与两个线程尝试进入synchronized同一对象上的块时的行为完全相同。第一个到达的线程将锁定对象监视器,立即完成锁定对象。另一个线程将阻塞,直到其锁定操作完成,即。在第一个线程解锁监视器之后。