我在项目中找到了打击代码。但我不明白为什么唯一的notify()方法是在synchronized块中。
synchronized(this){
notify();
}
此代码是否合乎逻辑,如果是,那么真正的目的是什么?
答案 0 :(得分:4)
您应该只从拥有该对象监视器的线程中调用notify
。来自the documentation:
此方法只能由作为此对象监视器所有者的线程调用。线程以三种方式之一成为对象监视器的所有者:
- 执行该对象的同步实例方法。
- 通过执行在对象上同步的同步语句的主体。
- 对于Class类型的对象,通过执行该类的同步静态方法。
(我的重点)
答案 1 :(得分:2)
要理解它为什么有意义,请考虑必须在同一个对象上同步其他块,这将被此块唤醒。
看看这个:
http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
答案 2 :(得分:2)
notify()唤醒在同一个对象上调用wait()的第一个线程。
class ThreadB extends Thread{
int total;
@Override
public void run(){
synchronized(this){
for(int i=0; i<100 ; i++){
total += i;
}
notify();
}
}
如上例所示,我们使用notify向其他正在等待的线程发送信息消息(嘿,我完成了我的工作,醒来!)。所以在你的问题上,它没有意义
答案 3 :(得分:1)
这不一定是错误的,但绝对是一个坏兆头。在该代码的其他地方,将存在无条件wait
。 E.g:
synchronized(this) {
wait();
}
这可能现在正常工作。但是,如果在notify
之前执行wait
,则会导致死锁。
通常你想在某种条件下等待:
synchronized(this) {
while(!this.flag) {
this.wait();
}
}
并像这样使用notify
:
synchronized(this) {
this.flag = true;
this.notify();
}
它永远不会自行陷入僵局,而且我们正在等待它们很清楚。