Spring @Scheduled @Async联合实现调度任务
Posted 蓝萝卜blu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring @Scheduled @Async联合实现调度任务相关的知识,希望对你有一定的参考价值。
定时任务之前一直用的是quartz之类,但是注意到Spring中其实也提供了一种简单的调度注释@Scheduled,也就想尝一下鲜..
代码示意如下:
@Component @EnableScheduling public class AsyncTaskHandlerTask { @Scheduled(fixedDelay = 1000) public void task1() { //输出日志 } @Scheduled(fixedDelay = 1000) public void task2() { //输出日志 } }
执行了一下,完全ok,日志打印正常,2个任务也都正常定时执行了.那好,添加些业务逻辑进去:
@Component @EnableScheduling public class AsyncTaskHandlerTask { @Scheduled(fixedDelay = 1000) public void task1() { while(true){ .... } } @Scheduled(fixedDelay = 1000) public void task2() { while(true){ .... } } }
再启动,咦,奇怪了,怎么定时任务没有执行呢?倘使我之前没有输出日志试验,我可能就认为注解的用法错了呢...重新添加日志,下断点重跟了一下启动过程发现:
程序进入到while死循环后就卡死了,没有再继续启动另一个定时任务了.通过现象可知@Scheduled启动过程是一个单线程同步启动过程,故一旦中途被阻塞,会导致整个启动过程阻塞,
其余的定时任务都不会启动.这明显很奇怪,网上的教程大多数是xml配置形式,Spring的官网我这头打开又奇慢无比..但是从xml的配置形式可知需要配置一个线程池来启动定时任
务.但是Javaconfig形式的则没有说明.但是我查询到了另一个注解@Async,这个异步注解我是使用过的,可以指定线程池,打到方法上后便会以指定的线程池来执行方法.然后解决方案来了:
@Component @EnableScheduling public class AsyncTaskHandlerTask { @Scheduled(fixedDelay = 1000) @Async public void task1() { while(true){ .... } } @Scheduled(fixedDelay = 1000) @Async public void task2() { while(true){ .... } } }
再次启动,不会再被阻塞.
以上是关于Spring @Scheduled @Async联合实现调度任务的主要内容,如果未能解决你的问题,请参考以下文章