Jar*_*zek 6 java multithreading
我写了一个永远不会停止的测试应用程序.它发布t.wait()(t是一个Thread对象),但我从不调用notify.为什么这段代码结束了?尽管主线程正在同步t,但生成的线程会运行,因此它不会锁定此对象.
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);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
结果是主线程等待5秒,在此期间工作人员给出其输出.然后在5秒钟结束后,程序退出.t.wait()不等 如果主线程不会睡5秒钟(注释这一行),那么t.wait()实际上会等到工作完成.当然,这join()是一种在这里使用的方法,但是,出乎意料的是,wait()它做了同样的事情join().为什么?
也许JVM看到了,因为只有一个线程正在运行,所以没有机会通知主线程并解决死锁问题.如果这是真的,它是一个记录的功能吗?
我正在测试Windows XP,Java 6.
Jon*_*eet 10
您正在等待Thread- 虽然大多数对象未被隐式通知,但Thread在线程终止时会通知对象.它记录的地方(我在寻找它...),你应该不使用wait/ notify上Thread对象,做为所内部完成.
这是为什么使用"私有"对象进行同步(以及等待/通知)的最佳实践的一个很好的例子 - 只有你的代码知道的东西.我经常使用类似的东西:
private final Object lock = new Object();
Run Code Online (Sandbox Code Playgroud)
(一般情况下,如果可以的话,使用java.util.concurrent提供的一些更高级别的抽象更清晰.如评论中所述,实现Runnable而不是扩展Thread自己也是一个好主意.)
该JavaDoc中的wait给出了答案:虚假唤醒是可能的.这意味着JVM可以随时结束调用wait.
如果您不想要这个(可能总是这样),文档甚至会为您提供解决方案:将调用wait置于循环中并检查每次唤醒后您等待的条件是否变为真.
| 归档时间: |
|
| 查看次数: |
1033 次 |
| 最近记录: |