I've been using spring boot with @Scheduled for a while, but recently I found there is a dangerous latent threat as described below: I found as application runs and Scheduled task run several times, there are many threads remaining waiting but not finished, which is shown in thread stacktrace by 'kill -3'. To clear anything that might leads to this problem, I make a totally dummy task:
@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());
}
}
and this is my log:
20151102 11:54:50.660 | INFO | pool-3-thread-2 | ---------------[26] | TestJob.test(TestJob.java:19) 20151102 11:55:50.662 | INFO | pool-3-thread-4 | ---------------[28] | TestJob.test(TestJob.java:19) 20151102 11:56:50.664 | INFO | pool-3-thread-5 | ---------------[33] | TestJob.test(TestJob.java:19) 20151102 11:57:50.666 | INFO | pool-3-thread-6 | ---------------[37] | TestJob.test(TestJob.java:19)
thread stacktrace:
"pool-3-thread-2" #26 prio=5 os_prio=0 tid=0x00007fbea0cd9800 nid=0x74f2 waiting on condition [0x00007fbf0d3d2000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x0000000763ed3710> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) 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.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088) at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809) 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:745)
"pool-3-thread-4" #28 prio=5 os_prio=0 tid=0x00007fbea0783800 nid=0x74f4 waiting on condition [0x00007fbf0d1d0000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x0000000763ed3710> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) 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.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088) at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809) 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:745)
the Scheduled javadoc says
Processing of @Scheduled annotations is performed by registering a ScheduledAnnotationBeanPostProcessor.
I haven't named this class myself, only with @EnableScheduling annotated main class.
Does anybody knows how to fix this problem?
I attached a picture of Eclipse debugging screen capture, the pool is increasing and all old threads are running... hope it can clarify my question.
UPDATE: I think I get it right this time. the default pool size of spring boot scheduler is 100, and all thread is in running state. I dont get it really, running on what? I think it should be wait on something, why not? Does anyone know how to configure spring boot scheduled pool size with annotation? I'm not using xml in my application and not willing to introduce it only for scheduler.