0

我一直在使用带有@Scheduled 的spring boot 一段时间,但最近我发现有一个危险的潜在威胁,如下所述:我发现当应用程序运行和计划任务运行多次时,有许多线程仍在等待但未完成,这在线程堆栈跟踪中由“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 (parking) at sun.misc.Unsafe.park(本机方法) - 在 java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent 停车等待 <0x0000000763ed3710> (一个 java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) .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) 在 java.util.concurrent.ThreadPoolExecutor。getTask(ThreadPoolExecutor.java:1067) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) 在 java.util.concurrent.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 (parking) at sun.misc.Unsafe.park(本机方法) - 在 java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent 停车等待 <0x0000000763ed3710> (一个 java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) .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) 在 java.util.concurrent.ThreadPoolExecutor。getTask(ThreadPoolExecutor.java:1067) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 在 java.lang.Thread .run(Thread.java:745)

预定的 javadoc 说

@Scheduled 注解的处理是通过注册一个 ScheduledAnnotationBeanPostProcessor 来执行的。

我自己没有命名这个类,只有 @EnableScheduling 带注释的主类。

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

更新: 我附上了一张Eclipse调试屏幕截图,池正在增加,所有旧线程都在运行......希望它能澄清我的问题。

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

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

4

1 回答 1

1

我在您的示例中看到了绝对正常的行为。您已经安排了任务,它每分钟由线程池中的不同线程执行。线程池中的线程处于线程池预期的 WAITING(parking) 状态。如果你想减少线程数,你可以配置:http: //docs.spring.io/spring/docs/4.0.x/spring-framework-reference/htmlsingle/#scheduling

<task:scheduler id="scheduler" pool-size="2"/>
于 2015-11-02T07:34:23.813 回答