为避免将自定义ThreadFactory
传递到ThreadPoolExecutor
以直接使用Executors.newCachedThreadPool();
。
我创建了一个线程mainDaemonThread
,使用Executors.newCachedThreadPool();
,提交任务,并且在mainDaemonThread
启动之前,我将其设置为daemon
,据我所知,一旦父级线程是一个守护进程,默认情况下,它创建的所有线程均为daemon
。
当在某个线程中运行的代码创建新的Thread对象时,新线程的优先级最初设置为与创建线程的优先级相等,并且当且仅当创建线程是守护程序时,该线程才是守护程序线程。
>
那么为什么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
任何帮助将不胜感激,谢谢〜
答案 0 :(得分:4)
我想这不是关于原因的正确答案,但是:
您链接的文档适用于Thread
类,并记录了“手动”创建新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)
方法与确实创建守护程序Thread
的工厂一起使用。由于ThreadFactory
是一个功能接口,因此就像
Executors#newCachedThreadPool(Thread::new);