0

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?

UPDATE: 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.

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.

1
  • Increasing the pool size would help? Commented Nov 2, 2015 at 6:43

1 Answer 1

1

I see absolutely normal behavior in your example. You have scheduled task, it's executed every minute by different thread in thread pool. Threads in thread pool are in WAITING(parking) state that is expected for thread pool. If you want to decrease number of threads you can configure that: http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/htmlsingle/#scheduling

<task:scheduler id="scheduler" pool-size="2"/> 
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks Anatoly, Actually I'm not going to increase or decrease the pool size, but want to terminate the thread. As I have shown above, the exact thread, is at waiting status, not terminated. each time the job runs, it created a new thread with extinct thread id, but the thread never terminates. Have you encountered this situations?
sorry I made a mistake, it's not always distinct each time. but it's true that the original thread seems not terminated.
the number of threads that are not terminated depends on your pool configuration. Threads are not terminated for performance reasons - it's the way how thread pool works. Just test it on number of executions more then your pool size and you will see that threads are reused.
that came to my mind before, but i have no idea how to configure this in spring boot, with annotation. With xml or native java executor, it's much simpler.
If you still want to terminate threads - use cached thread pool. "Creates a thread pool that creates new threads as needed, but will reuse previously constructed threads when they are available. These pools will typically improve the performance of programs that execute many short-lived asynchronous tasks. Calls to execute will reuse previously constructed threads if available. If no existing thread is available, a new thread will be created and added to the pool. Threads that have not been used for sixty seconds are terminated and removed from the cache"
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.