live thread 可以作为 gc root, 那么 waiting 状态的线程呢?

2023-03-28 12:12:30 +08:00
 lry

这个问题的背景是我发现项目中大量使用了 ExecutorService pool = Executors.newSingleThreadExecutor() 作为局部变量使用

而 JDK 8 中的 SingleThreadExecutor 是用 new FinalizableDelegatedExecutorService 包了一层,实现了 finalize 方法会调用线程池的 shutdown() 方法。

我觉得比较疑惑的是,方法调用完之后,ThreadPoolExecutor 中的 workers 仍然有着对核心线程的引用,为什么局部变量 pool 为什么会被回收。

996 次点击
所在节点    Java
4 条回复
karottc
2023-03-28 16:27:41 +08:00
finalize 执行时机不确定把,你手动 shutdown 试试
lry
2023-03-28 18:26:56 +08:00
@karottc 我感到奇怪的是为什么 pool 有着一个 waiting 状态的核心线程的引用,还会被 gc 回收走到 finalize 方法里
choice4
2023-03-28 19:26:40 +08:00
大概因为是局部变量。
困惑的点应该是有一个理解误区,就是线程池中的线程其实不对 ExecutorService 实例产生引用。
在 ExecutorService 局部变量生命周期结束后也就不存在外部对它的引用,这个对象可以被回收,进而停掉线程池,然后等待线程执行正常结束。
lry
2023-03-28 20:21:24 +08:00
@choice4 是我理解错了,,,局部变量 ExecutorService 实例对象在方法执行完了之后确实没地方引用它了,只是这个对象的 workers 字段引用了一个核心线程,但是并不影响这个实例对象的 gc...

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/927810

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX