Потоки, созданные в Executors.newCacheThreadPool, не являются демонами, хотя пул создан в демоне. - PullRequest
0 голосов
/ 28 июня 2018

Чтобы не передавать пользовательский ThreadFactory на ThreadPoolExecutor для непосредственного использования Executors.newCachedThreadPool();.

Я создал поток mainDaemonThread, использую Executors.newCachedThreadPool();, отправляю задачи и перед запуском mainDaemonThread я установил его daemon и, насколько я знаю, однажды поток parent является демоном, тогда все созданные им потоки будут 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

Любая помощь будет оценена, спасибо ~

1 Ответ

0 голосов
/ 28 июня 2018

Полагаю, это не совсем правильный ответ, почему:

Документ, на который вы ссылаетесь, предназначен для класса 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 s. Поскольку ThreadFactory является функциональным интерфейсом, это так же просто, как

Executors#newCachedThreadPool(Thread::new);
...