Executors.newCacheThreadPool 创建的线程不是守护进程,尽管池是在守护进程中创建的

Threads created by Executors.newCacheThreadPool is not daemon though the pool created within a Daemon

避免将自定义 ThreadFactory 传递给 ThreadPoolExecutor 以直接使用 Executors.newCachedThreadPool();

我创建了一个线程 mainDaemonThread,使用 Executors.newCachedThreadPool();,提交任务,在 mainDaemonThread 启动之前,我设置了它 daemon 据我所知,一旦 parent 线程是守护进程,那么它创建的所有线程默认都是 daemon

Daemon Thread

When code running in some thread creates a new Thread object, the new thread has its priority initially set equal to the priority of the creating thread, and is a daemon thread if and only if the creating thread is a daemon.

那么为什么 Executors.newCachedThreadPool(); 不遵守规则呢?一些与此相关的设计偏好?

import static java.lang.System.out;
public static void main(String... args) throws InterruptedException {
    Thread mainDaemonThread = new Thread(() -> {
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.submit(() -> {
            try {
                out.println(Thread.currentThread().isDaemon());
                Thread.sleep(1000);
                out.println(Thread.currentThread().isDaemon());
            } catch(InterruptedException ignored) {
                ignored.printStackTrace();
            }
        });
    });
    mainDaemonThread.setDaemon(true);
    mainDaemonThread.start();
    mainDaemonThread.join();
    out.println(Thread.currentThread().isDaemon());
}

演示的输出:

false
false
false

任何帮助将不胜感激,谢谢~

我想这不是一个真正正确的答案,但是:

您 link 的文档是针对 Thread class 的,并记录了 "manually" 创建新 Thread 的行为。它只是不适用于您提交给 ExecutorService 的任务(尽管我明白您为什么会这样期望)。

如果您查看源代码,newCachedThreadPool 执行程序使用(内部)DefaultThreadFactory 显式创建非守护进程 Thread:

public Thread newThread(Runnable r) {
    Thread t = new Thread(group, r,
                          namePrefix + threadNumber.getAndIncrement(),
                          0);
    if (t.isDaemon())
        t.setDaemon(false); // ta-da
    if (t.getPriority() != Thread.NORM_PRIORITY)
        t.setPriority(Thread.NORM_PRIORITY);
    return t;
}

如果您希望执行程序创建一个守护线程,您可以使用 Executors#newCachedThreadPool(ThreadFactory) 方法和一个创建守护进程 Threads 的工厂。由于 ThreadFactory 是函数式接口,所以这和

一样简单
Executors#newCachedThreadPool(Thread::new);