为什么运行ScheduleExecutorService的UserThread不会收集垃圾

Kes*_*115 6 java multithreading executorservice

请帮我在下面的代码中找到Thread泄漏的原因.该TestThread甚至运行后收集的数据不被垃圾()已完成(从安慰print语句验证)和主要方法已退出(从print语句和Profiler工具验证).

TestThread,但是,如果得到它被设置为守护线程即垃圾收集t.setDaemon(true).下面的代码只是一个示例代码,用于说明我的应用程序中的问题.我正在尝试使用一些预先存在的调度类(由其他人使用设计ScheduledExecutorService).我注意到,当我继续Runnable使用类调度多个s时,创建的线程永远不会被垃圾收集.

public class ThreadTest {

  static void runThreadWithExecutor() {
    final String name = "TestThread";
    ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor(
        new ThreadFactory() {
          @Override
          public Thread newThread(Runnable r) {
            Thread t = new Thread(r, name);
            t.setDaemon(false);
            return t;
          }
        });

    ses.schedule(new Runnable() {
        @Override
        public void run() {
           System.out.println("entered " + name);
           System.out.println("exiting " + name);
        }},
      2,
      TimeUnit.SECONDS);
    }

  public static void main(String[] args) throws InterruptedException {
    System.out.println("entered main");
    runThreadWithExecutor();
    Thread.sleep(5000);
    System.out.println("exiting main");
  }
}
Run Code Online (Sandbox Code Playgroud)

Gra*_*ray 5

这是因为shutdown()您在安排上一份工作后没有调用执行程序服务:

ses.schedule(...);
// this stops any management threads but existing jobs will still run
ses.shutdown();
Run Code Online (Sandbox Code Playgroud)

我刚刚添加了shutdown()对您的代码的调用,它退出正常.对所有人来说都是如此ExecutorService.如果没有关闭,线程池将继续等待提交更多作业,并且永远不会GC.

有关详细信息,请参阅下面@ John的答案.