代码之家  ›  专栏  ›  技术社区  ›  Rui

为什么从Executors实用程序类返回的ExecutorService的execute()方法不能自然终止

  •  1
  • Rui  · 技术社区  · 8 年前

    如我们所知, java.util.concurrent.Executors 包含许多方法,如

    • newCachedThreadPool
    • newFixedThreadPool
    • newScheduledThreadPool
    • newSingleThreadExecutor
    • newSingleThreadScheduledExecutor

      他们回来了 ExecutorService ,其中包含 execute(Runnable task) 方法。但是,当调用 执行(可运行任务) 属于 执行服务 从上述返回 工厂方法 ,它只能通过调用 shutdown() shutdownNow()

    例如,如果我们将以下代码添加到 main 方法,

    ExecutorService e = Executors.newSingleThreadExecutor();
    e.execute(() -> system.out.println("test")); 
    

    调用主程序永远不会作为 关闭() 立即关闭() 不被调用。所以包含以下代码片段的程序 主要的 将终止

    ExecutorService e = Executors.newSingleThreadExecutor();
    e.execute(() -> system.out.println("test"));
    e.shutdown();
    

    但是,一些 执行服务 比如打电话回来的那个 Executors.newWorkStealingPool 或者 ForkJoinPool 不需要调用就可以终止 关闭() 立即关闭()

    所以我的 问题 是: 为什么 execute() 执行服务 从上述返回 工厂方法 以“new”开头,不调用就不终止 关闭() 立即关闭() 从设计的角度来看?

    2 回复  |  直到 8 年前
        1
  •  0
  •   Denis Tulskiy    8 年前

    简要介绍Java线程:线程有两种类型:守护进程和非守护进程。当程序的所有非守护进程线程完成执行时,程序终止。守护进程线程只能在程序运行且不阻止终止时运行,例如。 garbage collector . 当Java程序启动时,除主线程之外的所有线程都是守护进程。

    newSingleThreadExecutor() 及其 defaultThreadFactory() 创建非守护进程线程。有点道理-你在创造一个 螺纹 那就等着工作吧,应该是你明确的打算把它关掉。

    另一方面,forkjoinpool将您从底层线程池中抽象出来。因此它可以使用守护进程线程,因为您通常希望等待任务执行。

        2
  •  0
  •   user3312330    8 年前

    芮,你的例子为什么挂起的答案很简单。默认情况下,ExcutoService中的线程是非守护进程线程,只要有非守护进程线程运行,Java程序就不会退出。如果不需要此行为,则只需定义一个创建守护进程线程的threadfactory,如下所示:

    public class Test {
        static ThreadFactory mThreadFactory = new ThreadFactory() {
            public Thread newThread(Runnable r) {
                Thread t = new Thread(r);
                t.setDaemon(true);
                return t;
            }
        };
    
        public static void main(String[] args) {
            ExecutorService e = Executors.newSingleThreadExecutor(mThreadFactory);
            e.execute(new Runnable() { public void run() { System.out.println("test"); } });
        }
    }