spring boot计划任务挂起

时间:2015-11-02 04:28:24

标签: spring spring-boot spring-scheduled

我已经和@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 |信息| pool-3-thread-2 | --------------- [26] | TestJob.test(TestJob.java:19)   20151102 11:55:50.662 |信息| pool-3-thread-4 | --------------- [28] | TestJob.test(TestJob.java:19)   20151102 11:56:50.664 |信息| pool-3-thread-5 | --------------- [33] | TestJob.test(TestJob.java:19)   20151102 11:57:50.666 |信息| pool-3-thread-6 | --------------- [37] | TestJob.test(TestJob.java:19)

线程堆栈跟踪:

  

"池-3-螺纹-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)           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)           在java.lang.Thread.run(Thread.java:745)

     

"池-3-螺纹-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)           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)           在java.lang.Thread.run(Thread.java:745)

计划的javadoc说

  

通过注册ScheduledAnnotationBeanPostProcessor来执行@Scheduled注释的处理。

我自己并没有将这个类命名,只能使用@EnableScheduling注释主类。

有人知道如何解决这个问题吗?

更新: 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.

我附上了Eclipse调试屏幕截图的图片,池正在增加,所有旧线程都在运行......希望它可以澄清我的问题。

更新: 我想我这次做对了。 spring boot scheduler的默认池大小为100,并且所有线程都处于运行状态。我真的不明白,依靠什么?我认为应该等待一些事情,为什么不呢? 有谁知道如何使用注释配置spring boot预定池大小?我没有在我的应用程序中使用xml,也不愿意仅为调度程序引入它。

1 个答案:

答案 0 :(得分:1)

我在你的例子中看到绝对正常的行为。 你有预定的任务,它由线程池中的不同线程每分钟执行一次。线程池中的线程处于线程池预期的WAITING(停放)状态。 如果要减少线程数,可以配置: the official Oracle Java tutorial

<task:scheduler id="scheduler" pool-size="2"/>