【问题标题】:Calling notify() vs ending synchronized block Java [duplicate]调用 notify() 与结束同步块 Java [重复]
【发布时间】:2018-10-17 13:08:07
【问题描述】:

我是线程编程的新手,我有如下的困惑。让我们看看下面的代码块。

synchronized(obj)
{
   //do operations
   //obj.notify();
   //post operations
   // last statement 
}

在“最后一条语句”执行之前,即使调用了 notify(),obj 的监视器也不会被释放。那么值得在这里调用 notify() 吗?因为反正当同步块退出时,不等于调用notify()。

【问题讨论】:

  • 您是在问一般的notify(恰好是wait 的对应物,不是同步块),还是在这样的块中间调用它?
  • 我的建议是永远忘记notify()。在这一点上,它是一个仅供专家使用的低级工具;如果你想构建依赖于状态的类,你应该在 java.util.concurrent 中构建顶级类,比如 Semaphore,如果你不需要状态依赖,你肯定不需要 notify()。
  • @GhostCat,我认为这个问题更像是 stackoverflow.com/questions/15886972/… 的重复问题,然后是你引用的问题
  • @tevemadar,是的,当代码块已经同步时,它带来了对对象调用通知的额外优势。
  • 使用wait()/notify() 来sequence 由多个线程执行的操作(例如,如果您想确保“消费者”线程不会尝试占用从容器中取出的东西,直到在“生产者”将其放入容器中。)但是,如果您只关心 A 和 B 不会同时发生——如果你不在乎哪个先发生——那么你只需要synchronized。

标签: java synchronized notify


【解决方案1】:

不,当您退出同步块时,既不会调用 notify() 也不会调用 notifyAll(),并且所有其他等待同一个锁调用 wait() 的线程都不会被唤醒。

以下是关于自动呼叫notifyAll() 的一些缺点 Automatic notify()/notifyAll() on leaving a synchronized block

【讨论】:

    【解决方案2】:

    当synchronized 块退出时,如果没有调用notify。它只允许试图进入synchronized 块的最终其他线程继续执行。
    notify 唤醒因调用wait 方法而暂停的单个线程。

    【讨论】:

      【解决方案3】:

      同步块将确保任何时候只有一个线程可以在该临界区。在对象上调用 notify() 将唤醒正在该对象的监视器上等待的单个线程,即 obj.wait()。

      在大多数情况下,您不需要使用 wait()、notify() 或 notifyAll(),包括上面的示例。

      我建议您也看看 Java 中的 Executor 包,它可以处理您的大部分复杂性。在线程方面很容易引起各种问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-04-01
        • 2013-03-01
        • 2010-10-08
        • 1970-01-01
        • 2017-03-19
        • 2012-11-19
        • 1970-01-01
        相关资源
        最近更新 更多