我在一个项目中找到了blow代码。但是我不明白为什么只有notify()方法在synchronized块中。
synchronized(this){
notify();
}
这段代码合乎逻辑吗?如果合乎逻辑,真正的目的是什么?
您应该只从拥有对象监视器的线程调用notify
。来自文档:
该方法只能由拥有该对象监视器的线程调用。线程通过以下三种方式之一成为对象监视器的所有者:
通过执行该对象的同步实例方法。
- 通过执行在对象上同步的同步语句体
- 对于Class类型的对象,通过执行该类的同步静态方法。
(我强调)
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向正在等待的其他线程发送信息消息(嘿,我完成了我的工作,唤醒!)所以对于你的问题,
要理解为什么它是有意义的,考虑到必须在同一对象上同步其他块,这些块将被这个块唤醒。
看一下这个:
http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html这不一定是不正确的,但绝对是一个不好的信号。在代码的其他地方,会有一个无条件的wait
。例如:
synchronized(this) {
wait();
}
现在可能工作正常。但是,如果notify
在wait
之前执行,这将导致死锁。
通常你想在某些条件下等待:
synchronized(this) {
while(!this.flag) {
this.wait();
}
}
和使用notify
如下:
synchronized(this) {
this.flag = true;
this.notify();
}
这将永远不会死锁自己,很清楚我们在等待什么。