【问题标题】:Java Threads: Wait don't work as expectedJava 线程:等待不按预期工作
【发布时间】:2015-02-28 17:12:01
【问题描述】:

当我学习如何使用等待和通知时,我得到一个奇怪的东西,下面两部分代码相似,但它们的结果却如此不同,为什么?

class ThreadT implements Runnable{



public void run()
  {
    synchronized (this) {

        System.out.println("thead:"+Thread.currentThread().getName()+" is over!");

    }

   }
}

public class TestWait1 {


public static void main(String[] args) {

    Thread A = new Thread(new ThreadT(),"A");
     A.start();
    synchronized (A) {

        try {
            A.wait();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
    System.out.println(Thread.currentThread().getName()+" is over");

}

}

结果:
标题:A结束了!
主线结束了

class ThreadD implements Runnable{

Object o  ;

public ThreadD(Object o)
{
    this.o = o;
}

public void run()
{
    synchronized (o) {

        System.out.println("thead:"+Thread.currentThread().getName()+" is over!");

    }


}
}

public class TestWait2 {


public static void main(String[] args) {

        Object o = new Object();

    Thread A = new Thread(new ThreadD(o),"A");

     A.start();

    synchronized (o) {

        try {
            o.wait();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
    System.out.println(Thread.currentThread().getName()+" is over");

}

}

结果:
头:A结束了!

为什么主函数可以在第一个示例中完成,但第二个示例主函数不能。它们有什么不同?

【问题讨论】:

    标签: java multithreading wait


    【解决方案1】:

    如果你在一个对象上调用 wait(),它会一直等到某个对象调用了 notify()。在您的第二个示例中,没有人调用 notify(),因此等待永远持续。在第一个示例中,线程 calls notifyAll() on it 的终止,导致 wait() 完成。

    【讨论】:

    • 对 OP 的重要说明:永远不要在 Thread 的实例上调用 wait/notify
    • @MarkoTopolnik,请告知为什么从不在线程的瞬间调用等待/通知?谢谢。
    • @PeterXu 在线程上调用notify() 是一个非常糟糕的主意,因为notify() 最多会唤醒一个wait()er。如果它不是您打算唤醒的线程,那么您的通知将丢失并且您的程序可能会挂起。 如果你做对了,在 Thread 对象上调用 wait() 是无害的,只是你的 wait()er 可能会在没有工作要做的时候被唤醒(又名,“虚假唤醒”),调用 notifyAll() 同样无害,只是您可能会虚假唤醒您无意唤醒的线程。
    • @PeterXu 您是否阅读过Thread#join 上的Javadoc,链接到哪个yole?那里有解释。我只是将其添加为明确的评论,因此它不会在链接后面丢失。基本上,线程使用Thread 的监视器进行自己的内部协调。这是出了名的糟糕设计,但我们坚持下去。
    【解决方案2】:

    @yole 是对的。在“Object o”上,没有正文调用 notify,但在第一种情况下,您正在等待 Thread 实例 notifyall 由 Thread 实例在退出时调用。

    这是另一个web link,它指的是您提出的相同问题。

    【讨论】:

      猜你喜欢
      • 2019-04-19
      • 1970-01-01
      • 1970-01-01
      • 2020-03-04
      • 2013-12-10
      • 2019-04-07
      • 2023-03-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多