Мы используем несколько пулов потоков на нашем 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 сервер часто не выключается, когда должен, и я подозреваю, что это может быть связано с тем, что некоторые потоки не являются потоками демонов, когда они должны.