我写了一个永远不会停止的测试应用程序。它发出t.wait()(t是一个Thread对象),但是我从不打电话通知。为什么此代码结束?尽管主线程在上同步t,但生成的线程仍在运行,因此不会锁定该对象。
t.wait()
t
Thread
public class ThreadWait { public static void main(String sArgs[]) throws InterruptedException { System.out.println("hello"); Thread t = new MyThread(); synchronized (t) { t.start(); Thread.sleep(5000); t.wait(); java.lang.System.out.println("main done"); } } } class MyThread extends Thread { public void run() { for (int i = 1; i <= 5; i++) { java.lang.System.out.println("" + i); try { Thread.sleep(500); } catch (Exception e) { throw new RuntimeException(e); } } } }
结果是主线程等待5秒钟,在此期间工作人员提供其输出。然后,在5秒钟后,程序退出。t.wait()不等。如果主线程在5秒钟内没有进入睡眠状态(对此行进行了注释),则t.wait()实际上将等到工作人员完成操作。当然,join()这里是一种使用方法,但是,出乎意料的是,wait()它与做相同的事情join()。为什么?
join()
wait()
也许JVM看到,由于仅运行一个线程,因此没有机会通知主线程并解决死锁。如果是这样,是否有文件记载的功能?
我正在Windows XP,Java 6上进行测试。
您正在等待Thread-,虽然大多数对象 都没有 隐式通知,Thread但线程终止时会通知一个对象。它记载的地方(我在寻找它…),你应该 不 使用wait/ notify上Thread对象,做为所内部完成。
wait
notify
这是一个很好的例子,说明为什么最佳实践是使用“私有”对象进行同步(和等待/通知)- 只有 您的代码才知道这一点。我通常使用类似:
private final Object lock = new Object();
(不过,总的来说,如果可以的话,使用java.util.concurrent提供的一些更高层次的抽象会更干净。如注释中所述,实现Runnable而不是扩展Thread自己也是一个好主意。)
Runnable