V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lry
V2EX  ›  Java

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

  •  
  •   lry · 2023-03-28 12:12:30 +08:00 · 811 次点击
    这是一个创建于 393 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    4 条回复    2023-03-28 20:21:24 +08:00
    karottc
        1
    karottc  
       2023-03-28 16:27:41 +08:00
    finalize 执行时机不确定把,你手动 shutdown 试试
    lry
        2
    lry  
    OP
       2023-03-28 18:26:56 +08:00
    @karottc 我感到奇怪的是为什么 pool 有着一个 waiting 状态的核心线程的引用,还会被 gc 回收走到 finalize 方法里
    choice4
        3
    choice4  
       2023-03-28 19:26:40 +08:00   ❤️ 1
    大概因为是局部变量。
    困惑的点应该是有一个理解误区,就是线程池中的线程其实不对 ExecutorService 实例产生引用。
    在 ExecutorService 局部变量生命周期结束后也就不存在外部对它的引用,这个对象可以被回收,进而停掉线程池,然后等待线程执行正常结束。
    lry
        4
    lry  
    OP
       2023-03-28 20:21:24 +08:00
    @choice4 是我理解错了,,,局部变量 ExecutorService 实例对象在方法执行完了之后确实没地方引用它了,只是这个对象的 workers 字段引用了一个核心线程,但是并不影响这个实例对象的 gc...
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5786 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 01:50 · PVG 09:50 · LAX 18:50 · JFK 21:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.