【问题标题】:Using wait() without notify() when in synchronized code piece (java)在同步代码片段(java)中使用wait()而不使用notify()
【发布时间】:2012-05-01 08:27:38
【问题描述】:

我想知道是否可以在不使用 notify() 的情况下在同步的代码上使用 wait(),如下所示:

wait_on(B):
    synchronized(B.monitor) {
    B.count--
        while (B.count > 0) { /* wait */ }
    }

提前致谢

【问题讨论】:

  • 当然,如果你想让它永远等待通知。
  • 如果没有notify(),您认为如何摆脱wait() 状态?您正在做的事情相当于在没有实际执行的情况下杀死线程。
  • 在没有同步的情况下还能用吗?

标签: java multithreading synchronization wait synchronized


【解决方案1】:

您需要 notify 或 notifyAll 将线程从等待状态中唤醒。在您的示例中,代码将进入等待并停留在那里(除非被中断)。

了解 wait、yield 和 sleep 之间的区别。需要在同步块中调用等待,一旦进入等待,锁就会被释放,并且线程保持在该状态直到调用通知。 Yield 将线程返回到就绪池,并让调度程序决定何时再次运行它。睡眠意味着线程休眠一段固定的时间(然后从那里进入就绪池)。

确保您在要同步的同一个对象上调用 wait(这里是 B.monitor)。

【讨论】:

  • 但是直到所有线程都会进入这个方法,并且最后一个会导致计数为0,然后它会出去,这会自动通知(),或者我错了吗?
  • @MichBoy:没有“自动”通知。一旦计数器变为 0,则不会有更多线程进入 while 循环的主体,这就是将发生的一切。
  • 如果我关闭同步?
  • @MichBoy:您是否尝试实现计数信号量?因为 java.util.concurrent 已经有了这些:docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/…
  • 我正在尝试做一些类似但不同的事情,如果没有同步它会工作吗?
【解决方案2】:

不!唯一的选择是等待超时,这肯定对您没有帮助。

【讨论】:

    【解决方案3】:

    如果你把/* wait */改成对wait()的调用,没有人会调用notify()或者notifyAll(),那么这个线程永远不会被唤醒……

    【讨论】:

      【解决方案4】:

      如果它是您想要的障碍,则需要通知所有其他线程:

      wait_on(B) {
          synchronized(B.monitor) {
              B.count--
              while (B.count > 0) {
                  B.monitor.wait()
              }
              B.monitor.notifyAll();
          }
      }
      

      问候,

      皮埃尔-吕克

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多