为什么"当一个线程调用d.wait时,它必须拥有d"的内在锁。

时间:2016-02-18 13:22:02

标签: java multithreading wait

我是Java的新手,正在尝试学习防护块的概念。我在Java教程oracle中看到了下面的代码和声明。我的问题是:

1)为什么"当一个线程调用d.wait时,它必须拥有d&#34的内在锁;?

2)声明中还提到了"否则会出现错误"。抛出什么样的错误?

public synchronized void guardedJoy() {
    // This guard only loops once for each special event, which may not
    // be the event we're waiting for.
    while(!joy) {
        try {
            wait();
        } catch (InterruptedException e) {}
    }
    System.out.println("Joy and efficiency have been achieved!");
}

以下是文章:

  

为什么这个版本的guardedJoy会同步?假设d是   我们用来调用等待的对象。当一个线程调用d.wait时,它   必须拥有d的内在锁 - 否则会抛出错误。   在同步方法中调用wait是一种简单的获取方法   本能锁定。

1 个答案:

答案 0 :(得分:2)

  

1)为什么“当一个线程调用d.wait时,它必须拥有d的内部锁”?

因为javadoc说它必须!

为什么?

waitnotify的主要目的是实现条件变量等。通常,一个线程等待某个其他线程通知它某些共享状态已更改。如果等待线程在锁中没有wait,那么就不能保证第二个线程所做的状态更改是可见的......根据Java内存模型。

你还需要担心比赛。例如,假设第三个线程也在等待相同的条件并获得不同的通知......并且只是刚刚安排了。现在你有两个线程都检查条件......在同一类型。 (注意,这仅适用于某些用例。)

  

2)声明中还提到“否则会抛出错误”。抛出什么样的错误?

javaoc说:“抛出...... IllegalMonitorStateException - 如果当前线程不是对象监视器的所有者。”

  

您能告诉我“当前主题不是对象监视器所有者”的潜在情况吗?

那就是当它没有通过输入synchronized块...或等价物获得锁定时。