【问题标题】:thread waits forever for notification case线程永远等待通知情况
【发布时间】:2013-09-26 13:13:44
【问题描述】:

在任何情况下都有可能在 ThreadA 中得到“永远等待”的情况。我的意思是通知执行速度比b.sync.wait();

class ThreadA {
      public static void main(String [] args) {
         ThreadB b = new ThreadB();

         b.start();

         synchronized(b.sync) 
         {
            try 
            {
               System.out.println("Waiting for b to complete...");
               b.sync.wait();
               System.out.println("waiting done");
            } catch (InterruptedException e) {}         
         }
      }
}

class ThreadB extends Thread {   
     int total=0; 
     Integer sync = new Integer(1);
     public void run() {


        synchronized(sync) 
        {
           sync.notify();
        }  
     }
}

【问题讨论】:

    标签: java multithreading happens-before


    【解决方案1】:

    是的,这是可能的。一旦调用b.start(),调度器可能会选择运行线程B,当线程A没有等待锁时,它会立即获取锁并调用notify。在这种情况下,威胁 A 稍后将获得锁定并继续等待。

    如果您需要确定性行为,则应仅在开始等待通知后致电b.start()

    【讨论】:

    • 这意味着在我的情况下,如果我需要避免休眠,我必须在 ThreadA 中等待时在某些 ThreadC 中调用 b.start()。
    • @user1501700 没错。一般来说,现在不鼓励使用wait()notify(),因为我们有java.util.concurrent 包。例如,CountDownLatch 会执行您需要的操作(A 中的 await(),B 中的 countDown())而无需同步。
    【解决方案2】:

    无法保证线程的执行顺序。 通知将在调用 wait() 之前发生是可能的(据我记得,线程在 Java 中的工作方式)。

    您几乎永远不能假设某件事会先于另一件事发生。

    有关创建前发生关系的操作列表,请参阅:Java Memory VisibilityThe Java™ Language Specification 的第 17 章

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多