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

时间:2014-11-02 16:53:34

标签: 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;
    }
}
在线程A释放锁定之前将调用

notify()(这将发生在“返回11 ;语句之后”)。 那么,等待此锁定的线程B(通过 wait()方法)如何获取仍由线程A保持的锁定? 请注意,当通知线程B时,线程A尚未释放锁定。

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

调用 wait()后,主题B会将其状态从正在运行更改为等待。 收到通知后(来自主题A notify()方法),主题B将从 wait()返回,将其状态更改为 Runnable ,试图获得锁定。由于线程A尚未释放锁定,因此线程B将在对象的监视器上被阻止,并将其状态从 Runnable 传递到阻止。 最后,在线程A释放锁定后,线程B将获得锁定并将其状态从阻止传递到正在运行

这是对的吗?我想通过这个问题理解的是对从 wait()返回的线程发生了什么,该线程已经被已获取的锁同步。

1 个答案:

答案 0 :(得分:1)

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

当您在对象上调用wait()时,调用线程将被添加到对象的wait set。当它为notify()时,它将从该等待集中删除,并对该对象执行a lock action(它位于该对象的synchronized块内)。该锁定动作将阻止当前线程直到它完成,即。锁定了对象监视器。

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