Spring @Scheduled @Async联合实现调度任务(2017.11.28更新)
定时任务之前一直用的是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){
....
}
} }
再次启动,不会再被阻塞.
2017-11-28更新:
本来以为找到了正解,结果证明是误入了歧途..以上是完全错误的使用,虽然看起来貌似是正确的..正应了一句话啊,啥都不如看源码啊...
太懒了,本来这个应该再单独开个文章再说的,但是太懒了...
进入正题,按照如上实现部署后突然发现一个诡异的问题,定时任务发生了异常的"阻塞"现象,某个任务突然看起来不再执行了,直接卡死了.第一印象是死锁了,直接jstack生成了一份堆栈信息,仔细分析后发现一个诡异问题,定时任务并没有像Scheduled定义的那样一次结束后再执行下一次,而是并发执行多次,直接将Async定义的线程池跑满.那么问题也就好解释了,Async注解后,直接异步在新线程中执行任务,由于异步执行Scheduled认为上一次已经执行完马上开始执行下一次,导致不停执行定时任务直接跑满Async使用的线程池.那么这实际上是一种错误的使用方法..怎么办?
只好点了@EnableScheduling注解看一下源码中怎么说的吧.
* <p>When more control is desired, a {@code @Configuration} class may implement
* {@link SchedulingConfigurer}. This allows access to the underlying
* {@link ScheduledTaskRegistrar} instance. For example, the following example
* demonstrates how to customize the {@link Executor} used to execute scheduled
* tasks:
实际上已经说的很明白了,更多的控制,只需要继承 SchedulingConfigurer 这个类,之前没有找到对应xml中配置线程池的方法也正是如此.
* public class AppConfig implements SchedulingConfigurer {
*
* @Override
* public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
* taskRegistrar.setScheduler(taskExecutor());
* }
*
* @Bean(destroyMethod="shutdown")
* public Executor taskExecutor() {
* return Executors.newScheduledThreadPool(100);
* }
* }
标红处就是使用线程池的配置,之后再执行不仅以多线程来启动定时任务,而且也不会出现定时任务重复并发执行的问题.至此此问题圆满解决.再感叹下啥都不如看源码.
Spring @Scheduled @Async联合实现调度任务(2017.11.28更新)的更多相关文章
- Xamarin 2017.11.9更新
Xamarin 2017.11.9更新 本次更新主要针对Xamarin.iOS,适配了iOS 11.1和Xcode 9.1.Visual Studio 2017升级到15.4.3获得新功能.Visu ...
- Xamarin 2017.11.1更新
Xamarin 2017.11.1更新 本次更新主要解决了一些bug.Visual Studio 2017升级到15.4.2获得新功能.Visual Studio 2015需要工具-选项-Xamar ...
- 2017.11.28 Enginering management:problem-solving ability
Today,my colleague is on bussiness trip. going to customer factory in jiangxi. slove the color diffe ...
- Spring Boot @Async 异步任务执行
1.任务执行和调度 Spring用TaskExecutor和TaskScheduler接口提供了异步执行和调度任务的抽象. Spring的TaskExecutor和java.util.concurre ...
- Spring @Scheduled Annotation
1.Overview 这里我们将会学习Spring @Scheduled 标签,了解它是如何配置,如何设置定时任务. 关于它的使用,有两点简单的规则需要记住: ※它的方法应该是一个void返回值类型 ...
- 定时任务 spring @Scheduled注解
使用spring @Scheduled注解执行定时任务: 运行!!! 关于Cron表达式(转载) 表达式网站生成: http://cron.qqe2.com/ 直接点击 cronExpression ...
- Spring @Scheduled应用解析
最近,遇到的一个需求,需要执行定时任务,每个一定时间需要执行某个方法 因为项目是SpringMVC的项目,所以使用的是Spring @Scheduled(由于quartz应用起来太麻烦,所以没有采用) ...
- 使用轻量级Spring @Scheduled注解执行定时任务
WEB项目中需要加入一个定时执行任务,可以使用Quartz来实现,由于项目就一个定时任务,所以想简单点,不用去配置那些Quartz的配置文件,所以就采用了Spring @Scheduled注解来实现了 ...
- spring计划任务,springMvc计划任务,Spring@Scheduled,spring定时任务
spring计划任务,springMvc计划任务,Spring@Scheduled,spring定时任务 >>>>>>>>>>>> ...
随机推荐
- VirtualBox-- 虚拟机网络设置2--主机与虚拟机互相访问且均上外网
转载自:http://blog.sina.com.cn/s/blog_7de9d5d80100t2uw.html VirtualBox中有4中网络连接方式:NATBridged AdapterIn ...
- python 部分函数
abs(number) ,返回数字的绝对值cmath.sqrt(number) ,返回平方根,也可以应用于负数float(object) ,把字符串和数字转换为浮点数help() ,提供交互式帮助in ...
- selenium 指定滚动到某个元素
from selenium import webdriver from selenium.common.exceptions import NoSuchElementException from se ...
- springboot + mybatis 的项目,实现简单的CRUD
以前都是用Springboot+jdbcTemplate实现CRUD 但是趋势是用mybatis,今天稍微修改,创建springboot + mybatis 的项目,实现简单的CRUD 上图是项目的 ...
- Python安装第三方库的安装技巧
电脑:Windows10 64位. Python IDE 软件:JetBrains PyCharm Community Edition 2018.1.3 x64 Python version : Py ...
- VC.时间(网页内容收集)
1.VC++获得当前系统时间的几种方案_记忆53秒_新浪博客.html(http://blog.sina.com.cn/s/blog_676271a60101i0hb.html) 1.1.内容保存: ...
- HDU 2569(简单的递推)
彼岸 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submissi ...
- docker-compose在dockerfile更新后自动更新image
比如在dockerfile里需要新安装包 形如 加一行 RUN pip3 install XXX 之后,希望docker-compose能更新镜像, 然后启动容器 只需要启动时使用 --build即可 ...
- CC初试啼声-----演讲与我
演讲与我 我非常讨厌演讲,因为我不会演讲,当我站在许多人面前讲话时,我会非常的紧张,我会血压升高,心跳加速,后背冒冷汗. 第一次演讲应该是在我初二的时候,期末考试结束,班级前五名的同学要做一个分享,我 ...
- English trip V1 - B 5.Is It Cold Outside? 外面很冷? Teacher:Corrine Key: weather
In this lesson you will learn to talk about the weather. 本节课将学习到关于天气 课上内容(Lesson) 词汇(Key Word ) # 关于 ...