Надежен ли "(демон)" в Java Thread-Dumps? - PullRequest
1 голос
/ 07 мая 2020

Мы используем несколько пулов потоков на нашем Java сервере, и один из пулов потоков должен содержать только потоки «deamon».

Я использую фабрику потоков, которая вызывает setDaemon (true) для этот пул, и я использую свой собственный подкласс Thread, который выглядит так:

private static final class DaemonThread extends Thread {
    public DaemonThread(ThreadGroup group, Runnable target,
        String name, long stackSize) {
        super(group, target, name, stackSize);
    }

    @Override
    public void run() {
        if (!isDaemon()) {
            LOG.error("Wrong state for isDaemon(): false");
        }
        super.run();
    }
}

Итак, я ожидаю увидеть что-то вроде этого, когда я делаю Thread-Dump:

"DAEMON-pool-1-thread-1234" Id=61 in WAITING on lock
    =java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@2030c72c (daemon)
    at sun.misc.Unsafe.park(Native Method)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:748)
    at com.company.thread.task.Task$TaskThreadFactory$DaemonThread.run(Task.java:194)

    Locked synchronizers: count = 0

Но я тоже вижу нечто подобное (без "(daemon)"):

"DAEMON-pool-1-thread-3287" Id=3383 in TIMED_WAITING on lock
    =java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@69e4d79b
    at sun.misc.Unsafe.park(Native Method)
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.poll(ScheduledThreadPoolExecutor.java:1134)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.poll(ScheduledThreadPoolExecutor.java:809)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1066)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:748)
    at com.company.thread.task.Task$TaskThreadFactory$DaemonThread.run(Task.java:194)

    Locked synchronizers: count = 0

Как вы могли заметить из нижней строки, Thread, который выполняет не говорят, что "(демон)" принадлежит к моему подклассу.

Во-первых, это должен быть демон, потому что его устанавливает пул потоков, а во-вторых, если это не демон, то я должен см. журнал ошибок, который я тоже не могу найти в наших журналах.

Итак, idk, если вывод дампа потока «неправильный», а поток - это демон, или если он not daemon, и вывод журнала каким-то образом теряется, или если каким-то образом состояние демона изменяется после , поток создается, то есть A FAIK, не разрешено:

https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#setDaemon -boolean-

Этот метод должен быть вызван до запуска потока.

Почему я хочу это знать? Потому что наш Java сервер часто не выключается, когда должен, и я подозреваю, что это может быть связано с тем, что некоторые потоки не являются потоками демонов, когда они должны.

...