我是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是一种简单的获取方法 本能锁定。
答案 0 :(得分:2)
1)为什么“当一个线程调用d.wait时,它必须拥有d的内部锁”?
因为javadoc说它必须!
为什么?
wait
和notify
的主要目的是实现条件变量等。通常,一个线程等待某个其他线程通知它某些共享状态已更改。如果等待线程在锁中没有wait
,那么就不能保证第二个线程所做的状态更改是可见的......根据Java内存模型。
你还需要担心比赛。例如,假设第三个线程也在等待相同的条件并获得不同的通知......并且只是刚刚安排了。现在你有两个线程都检查条件......在同一类型。 (注意,这仅适用于某些用例。)
2)声明中还提到“否则会抛出错误”。抛出什么样的错误?
javaoc说:“抛出...... IllegalMonitorStateException
- 如果当前线程不是对象监视器的所有者。”
您能告诉我“当前主题不是对象监视器所有者”的潜在情况吗?
那就是当它没有通过输入synchronized
块...或等价物获得锁定时。