Некоторое время я использовал весеннюю загрузку с @Scheduled, но недавно я обнаружил, что существует опасная скрытая угроза, как описано ниже: я обнаружил, что при запуске приложения и выполнения запланированной задачи несколько раз остается много потоков, ожидающих, но не завершенных, что показано в трассировке стека потока как «kill -3». Чтобы очистить все, что может привести к этой проблеме, я делаю пустую задачу:
@Component
public class TestJob
{
/**
* LOGGER
*/
private static Logger log = LogManager.getLogger(TestJob.class);
@Scheduled(fixedDelay = 60000, initialDelay = 1000)
public void test()
{
log.info("---------------[{}]", Thread.currentThread().getId());
}
}
а это мой журнал:
20151102 11: 54: 50.660 | ИНФОРМАЦИЯ | бассейн-3-поток-2 | --------------- [26] | TestJob.test (TestJob.java:19) 20151102 11: 55: 50.662 | ИНФОРМАЦИЯ | бассейн-3-поток-4 | --------------- [28] | TestJob.test (TestJob.java:19) 20151102 11: 56: 50.664 | ИНФОРМАЦИЯ | бассейн-3-поток-5 | --------------- [33] | TestJob.test (TestJob.java:19) 20151102 11: 57: 50.666 | ИНФОРМАЦИЯ | бассейн-3-поток-6 | --------------- [37] | TestJob.test (TestJob.java:19)
поток стека:
"pool-3-thread-2" # 26 prio = 5 os_prio = 0 tid = 0x00007fbea0cd9800 nid = 0x74f2 ожидание при условии [0x00007fbf0d3d2000] java.lang.Thread.State: WAITING (парковка) на sun.misc.Unsafe.park ( Собственный метод) - парковка для ожидания ‹0x0000000763ed3710> (объект java.util.concurrent.locks.AbstractQueuedSynchronizer $ ConditionObject) в java.util.concurrent.locks.LockSupport.park (LockSupport.java:175) в java.rentutil. .locks.AbstractQueuedSynchronizer $ ConditionObject.await (AbstractQueuedSynchronizer.java:2039) в java.util.concurrent.ScheduledThreadPoolExecutor $ DelayedWorkQueue.take (ScheduledThreadPoolExecutor.java:1088.consreadoolExecutor.java:1088. : 809) на java.util.concurrent.ThreadPoolExecutor.getTask (ThreadPoolExecutor.java:1067) на java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1127) на java.util. current.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.java:617) в java.lang.Thread.run (Thread.java:745)
"pool-3-thread-4" # 28 prio = 5 os_prio = 0 tid = 0x00007fbea0783800 nid = 0x74f4 ожидание при условии [0x00007fbf0d1d0000] java.lang.Thread.State: WAITING (парковка) в sun.misc.Unsafe.park ( Собственный метод) - парковка для ожидания ‹0x0000000763ed3710> (объект java.util.concurrent.locks.AbstractQueuedSynchronizer $ ConditionObject) в java.util.concurrent.locks.LockSupport.park (LockSupport.java:175) в java.rentutil. .locks.AbstractQueuedSynchronizer $ ConditionObject.await (AbstractQueuedSynchronizer.java:2039) в java.util.concurrent.ScheduledThreadPoolExecutor $ DelayedWorkQueue.take (ScheduledThreadPoolExecutor.java:1088.consreadoolExecutor.java:1088. : 809) на java.util.concurrent.ThreadPoolExecutor.getTask (ThreadPoolExecutor.java:1067) на java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1127) на java.util. current.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.java:617) в java.lang.Thread.run (Thread.java:745)
Запланированный javadoc говорит
Обработка аннотаций @Scheduled выполняется путем регистрации ScheduledAnnotationBeanPostProcessor.
Я сам не назвал этот класс, только с аннотированным основным классом @EnableScheduling.
Кто-нибудь знает, как исправить эту проблему?
Я прикрепил изображение захвата экрана отладки Eclipse, пул увеличивается, и все старые потоки работают ... надеюсь, это поможет прояснить мой вопрос.
ОБНОВЛЕНИЕ: я думаю, что на этот раз я все понял. размер пула весеннего планировщика загрузки по умолчанию равен 100, и все потоки находятся в рабочем состоянии. Я не понимаю, на чем работает? Я думаю, надо чего-нибудь подождать, почему бы и нет? Кто-нибудь знает, как настроить размер запланированного пула весенней загрузки с аннотацией? Я не использую xml в своем приложении и не хочу вводить его только для планировщика.