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

Why does the execute() method of ExecutorService returned from Executors utility class could not terminate naturally

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

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

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

调用主程序将永远不会终止,因为 shutdown()shutdownNow() 不会被调用。因此,在 main 中包含以下代码片段的程序将终止

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

但是,ExecutorService 的某些子类,例如通过调用 Executors.newWorkStealingPoolForkJoinPool 编辑的 return 可以在不调用 shutdown()shutdownNow()

所以我的问题是:为什么 ExecutorService return 的 execute() 来自上述 工厂方法 从设计的角度来看,如果不调用 shutdown()shutdownNow(),以“new”开始不会终止?

Rui,您的示例挂起的原因很简单。默认情况下,ExecutorService 中的线程是非守护线程,只要有非守护线程运行,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"); } });
    }
}

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

newSingleThreadExecutor() 及其 defaultThreadFactory() 创建非守护线程。这有点道理 - 您正在创建一个等待工作的 线程 池,您应该明确打算将其关闭。

另一方面,ForkJoinPool 将您从底层线程池中抽象出来。所以它可以使用守护线程,因为通常你打算等待任务执行。