码迷,mamicode.com
首页 > 编程语言 > 详细

Spring @Scheduled @Async联合实现调度任务

时间:2017-11-07 22:58:10      阅读:1376      评论:0      收藏:0      [点我收藏+]

标签:注意   方法   简单   调度   blog   family   解决方案   com   esc   

定时任务之前一直用的是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联合实现调度任务

标签:注意   方法   简单   调度   blog   family   解决方案   com   esc   

原文地址:http://www.cnblogs.com/chyu/p/7801521.html

(0)
(1)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!