我刚刚遇到了一个有趣的问题。似乎,如果在 Java 中,一个线程调用System.exit()
它就不能通过Thread.join()
.
这引起了我的问题,因为我想在我的应用程序之后使用关闭挂钩进行清理,例如:
Runtime.getRuntime.addShutdownHook(new Thread() {
public void run() {
reader.join();
writer.join();
in.close();
out.close();
}
});
这个想法是它确保线程在关闭这些资源之前已经完成了它们各自的资源。问题是有 3 种情况可以调用关闭挂钩。他们是:
- 用户点击 [ctrl] + [C]。
- 阅读器线程完成,并调用
System.exit()
. - Writer 线程完成,并调用
System.exit()
.
第一种情况,用户点击 [ctrl] + [C] 可以正常工作。但在其他两种情况下,关闭挂钩会永远阻塞。这是一个连锁效应,Thread.join()
即针对已经调用过的线程调用的oneSystem.exit()
永远阻塞。
因此,我有 2 个问题。首先,我知道我可以改用Thread.join(long millis)
它们,这样它们就不会无限期地阻塞,但是谁能想到一个更优雅的解决方案?其次,虽然一个人可以调用Thread.join()
同一个线程两次,而第二次它会立即返回,有没有人知道为什么调用Thread.join()
一个已经System.exit()
无限期调用块并且不立即返回的线程的原因?