synchronized块中的notify()

时间:2014-06-27 14:59:47

标签: java

我在项目中找到了打击代码。但我不明白为什么唯一的notify()方法是在synchronized块中。

synchronized(this){
  notify();
}

此代码是否合乎逻辑,如果是,那么真正的目的是什么?

4 个答案:

答案 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();
}

它永远不会自行陷入僵局,而且我们正在等待它们很清楚。