【发布时间】:2011-12-05 09:35:28
【问题描述】:
在这个代码示例中,ExecutorService 被使用一个并且允许超出范围。
public static void main(String[] args)
{
ExecutorService executorService = Executors.newFixedThreadPool(3);
executorService.submit(new Runnable()
{
public void run()
{
System.out.println("hello");
}
});
}
一旦 executorService 超出范围,它应该被收集并最终确定。 ThreadPoolExecutor 中的 finalize() 方法调用了 shutdown()。
/**
* Invokes {@code shutdown} when this executor is no longer
* referenced and it has no threads.
*/
protected void finalize() {
shutdown();
}
一旦调用了shutdown(),池线程应该终止并且JVM应该被允许退出。但是 executorSerivce 永远不会被收集,因此 JVM 仍然存在。甚至对 System.gc() 的调用似乎也不起作用。为什么即使在 main() 终止后 executorService 也没有被收集?
注意:我知道我应该自己调用 shutdown(),而且我总是在测试之外进行。我很好奇为什么最终确定在这里不能作为备份。
【问题讨论】:
-
因为垃圾收集是“非确定性的”,即您无法预测它何时会发生,因此您无法准确预测 finalize 方法何时运行。您只能使 Objects 符合 GC 的条件,并在没有任何保证的情况下使用 System.gc() 建议 gc
-
你永远不应该依赖终结来关闭或关闭某些东西。正如 jpse 已经说过的,垃圾收集是不确定的,并且不保证最终会运行。
-
JVM 没有退出,因为工作线程在 workQueue.take() 中被阻塞;
标签: java concurrency garbage-collection