boot定时任务开启和关闭 spring_SpringBoot中的定时任务的同步与异步你确定真的知道?...
定时任务调度功能在我们的开发中是非常常见的,随便举几个例子:定时清除一些过期的数据,定时发送邮件等等,实现定时任务调度的方式也十分多样,本篇文章主要学习各种实现定时任务调度方式的优缺点,以便为日后选择的时候提供一定的参考。
本篇要点
- 介绍Timer实现定时任务。
- 介绍ScheduledExecutorService实现定时任务。
- 介绍SpringBoot使用SpringTask实现定时任务。
- 介绍SpringBoot使用SpringTask实现异步任务。
Timer实现定时任务
基于JDK自带的java.util.Timer,通过调度java.util.TimeTask让某一段程序按某一固定间隔,在某一延时之后定时执行。
缺点:
- 无法指定某一时间的时候执行。
- 存在潜在bug,Timer运行多个TimeTask时,只要其中之一没有捕获抛出的异常,其它任务便会自动终止运行。
public class DemoTimer { //延时时间 private static final long DELAY = 3000; //间隔时间 private static final long PERIOD = 5000; public static void main(String[] args) { // 定义要执行的任务 TimerTask task = new TimerTask() { @Override public void run() { System.out.println("任务执行 --> " + LocalDateTime.now()); } }; Timer timer = new Timer(); timer.schedule(task, DELAY, PERIOD); }}
ScheduledExecutorService实现定时任务
阿里巴巴开发规范明确规定:希望开发者使用ScheduledExecutorService代替Timer。
多线程并行处理定时任务时,Timer运行多个TimeTask时,只要其中之一没有捕获抛出的异常,其它任务便会自动终止运行,使用ScheduledExecutorService则没有这个问题。
public class DemoScheduledExecutorService { //延时时间 private static final long DELAY = 3000; //间隔时间 private static final long PERIOD = 5000; public static void main(String[] args) { Runnable task = new Runnable() { @Override public void run() { System.out.println("任务执行 --> " + LocalDateTime.now()); } }; ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor(); service.scheduleAtFixedRate(task, DELAY, PERIOD, TimeUnit.MILLISECONDS); }}
SpringBoot使用Spring Task实现定时任务
自动配置实现原理
Spring为我们提供了异步执行任务调度的方式,提供TaskExecutor,TaskScheduler接口,而SpringBoot的自动配置类org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration为我们默认注入了他们的实现:ThreadPoolTaskScheduler,本质上是ScheduledExecutorService 的封装,增强在调度时间上的功能。
@ConditionalOnClass(ThreadPoolTaskScheduler.class)@Configuration(proxyBeanMethods = false)@EnableConfigurationProperties(TaskSchedulingProperties.class)@AutoConfigureAfter(TaskExecutionAutoConfiguration.class)public class TaskSchedulingAutoConfiguration {@Bean@ConditionalOnBean(name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)@ConditionalOnMissingBean({ SchedulingConfigurer.class, TaskScheduler.class, ScheduledExecutorService.class })public ThreadPoolTaskScheduler taskScheduler(TaskSchedulerBuilder builder) {return builder.build();}@Bean@ConditionalOnMissingBeanpublic TaskSchedulerBuilder taskSchedulerBuilder(TaskSchedulingProperties properties,ObjectProvider taskSchedulerCustomizers) {TaskSchedulerBuilder builder = new TaskSchedulerBuilder();builder = builder.poolSize(properties.getPool().getSize());Shutdown shutdown = properties.getShutdown();builder = builder.awaitTermination(shutdown.isAwaitTermination());builder = builder.awaitTerminationPeriod(shutdown.getAwaitTerminationPeriod());builder = builder.threadNamePrefix(properties.getThreadNamePrefix());builder = builder.customizers(taskSchedulerCustomizers);return builder;}}
新建工程,引入依赖
Spring Task是Spring Framework中的模块,我们只需引入spring-boot-starter依赖就可以了。
org.springframework.boot spring-boot-starter
编写配置类@EnableScheduling
@Configuration@EnableSchedulingpublic class ScheduleConfig {}
- @Configuration表明这是个配置类。
- @EnableScheduling表明启用Spring的定时任务调度功能。
定义定时任务@Scheduled
@Component@Slf4jpublic class DemoTask { private final AtomicInteger counts = new AtomicInteger(); @Scheduled(cron = "0/5 * * * * *") public void execute() { log.info("[定时任务第 {} 次执行]", counts.incrementAndGet()); }}
- @Component表明该类需要被扫描,以便于Spring容器管理。
- @Scheduled标注需要调度执行的方法,定义执行规则,其必须指定cron、fixedDelay或fixedRate三个属性其中一个。cron:定义Spring cron表达式,网上有在线cron生成器,可以对照着编写符合需求的定时任务。fixedDelay :固定执行间隔,单位:毫秒。注意,以调用完成时刻为开始计时时间。fixedRate :固定执行间隔,单位:毫秒。注意,以调用开始时刻为开始计时时间。
主启动类
@SpringBootApplicationpublic class SpringBootTaskApplication { public static void main(String[] args) { SpringApplication.run(SpringBootTaskApplication.class, args); }}
定义配置文件
Spring Task 调度任务的配置,对应 TaskSchedulingProperties 配置类。SpringBoot允许我们在yml或properties定制这些外部化配置,如果不配置也是没有关系的,自动配置已经给你一套默认的值了。
spring: task: scheduling: thread-name-prefix: summerday- # 线程池的线程名的前缀。默认为 scheduling- ,建议根据自己应用来设置 pool: size: 10 # 线程池大小。默认为 1 ,根据自己应用来设置 shutdown: await-termination: true # 应用关闭时,是否等待定时任务执行完成。默认为 false ,建议设置为 true await-termination-period: 60 # 等待任务完成的最大时长,单位为秒。默认为 0 ,根据自己应用来设置
启动项目测试
# 初始化一个 ThreadPoolTaskScheduler 任务调度器2020-11-30 23:04:51.886 INFO 10936 --- [ restartedMain] o.s.s.c.ThreadPoolTaskScheduler : Initializing ExecutorService 'taskScheduler'# 每5s执行一次定时任务2020-11-30 23:04:55.002 INFO 10936 --- [ summerday-1] com.hyh.task.DemoTask : [定时任务第 1 次执行]2020-11-30 23:05:00.002 INFO 10936 --- [ summerday-1] com.hyh.task.DemoTask : [定时任务第 2 次执行]2020-11-30 23:05:05.002 INFO 10936 --- [ summerday-2] com.hyh.task.DemoTask : [定时任务第 3 次执行]2020-11-30 23:05:10.001 INFO 10936 --- [ summerday-1] com.hyh.task.DemoTask : [定时任务第 4 次执行]2020-11-30 23:05:15.002 INFO 10936 --- [ summerday-3] com.hyh.task.DemoTask : [定时任务第 5 次执行]
SpringTask异步任务
SpringTask除了@Scheduled、@EnableScheduling同步定时任务之外,还有@Async、@EnableAsync 开启异步的定时任务调度。
SpringBoot自动配置类对异步的支持:org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration
@Async注解添加
@Async @Scheduled(cron = "0/1 * * * * *") public void asyncTask() { sleep(); System.out.println(Thread.currentThread().getName() + " async-task 执行,当前时间: " + LocalDateTime.now()); }
@EnableAsync注解添加
@Configuration@EnableScheduling // 同步@EnableAsync // 异步public class ScheduleConfig {}
配置文件
spring: task: # Spring 执行器配置,对应 TaskExecutionProperties 配置类。对于 Spring 异步任务,会使用该执行器。 execution: thread-name-prefix: async- # 线程池的线程名的前缀。默认为 task- ,建议根据自己应用来设置 pool: # 线程池相关 core-size: 8 # 核心线程数,线程池创建时候初始化的线程数。默认为 8 。 max-size: 20 # 最大线程数,线程池最大的线程数,只有在缓冲队列满了之后,才会申请超过核心线程数的线程。默认为 Integer.MAX_VALUE keep-alive: 60s # 允许线程的空闲时间,当超过了核心线程之外的线程,在空闲时间到达之后会被销毁。默认为 60 秒 queue-capacity: 200 # 缓冲队列大小,用来缓冲执行任务的队列的大小。默认为 Integer.MAX_VALUE 。 allow-core-thread-timeout: true # 是否允许核心线程超时,即开启线程池的动态增长和缩小。默认为 true 。 shutdown: await-termination: true # 应用关闭时,是否等待定时任务执行完成。默认为 false ,建议设置为 true await-termination-period: 60 # 等待任务完成的最大时长,单位为秒。默认为 0 ,根据自己应用来设置
同步与异步对比
@Componentpublic class DemoAsyncTask { @Scheduled(cron = "0/1 * * * * *") public void synTask() { sleep(); System.out.println(Thread.currentThread().getName() + " syn-task 执行,当前时间: " + LocalDateTime.now()); } @Async @Scheduled(cron = "0/1 * * * * *") public void asyncTask() { sleep(); System.out.println(Thread.currentThread().getName() + " async-task 执行,当前时间: " + LocalDateTime.now()); } private void sleep() { try { Thread.sleep(10 * 1000); } catch (InterruptedException e) { e.printStackTrace(); } }}
同时开启同步和异步任务,假设任务本身耗时较长,且间隔较短:间隔1s,执行10s,同步与异步执行的差异就此体现。
可以看到,同步任务并没有每间隔1s就执行,而是串行在一起,等前一个任务执行完才执行。而异步任务则不一样,成功将串行化的任务并行化。
原文链接:https://www.cnblogs.com/summerday152/p/14070941.html
如果觉得本文对你有帮助,可以转发关注支持一下
boot定时任务开启和关闭 spring_SpringBoot中的定时任务的同步与异步你确定真的知道?...相关推荐
- boot定时任务开启和关闭 spring_spring-boot 多线程并发定时任务的解决方案
刚刚看了下Spring Boot实现定时任务的文章,感觉还不错.Spring Boot 使用Spring自带的Schedule来实现定时任务变得非常简单和方便.在这里个大家分享下. 开启缓存注解 @S ...
- boot定时任务开启和关闭 spring_SpringBoot之定时任务详解
一.静态:基于注解 基于注解@Scheduled默认为单线程,开启多个任务时,任务的执行时机会受上一个任务执行时间的影响. 1.创建定时器 使用SpringBoot基于注解来创建定时任务非常简单,只需 ...
- boot定时任务开启和关闭 spring_Spring-Boot 下定时任务通过配置文件控制开关和执行时间...
配置文件读取cron表达式,启动定时任务 定时任务开关关键点(获取系统配置文件参数后添加:-) @Scheduled(cron = "${cron:-}") 首先配置文件添加@Sc ...
- boot定时任务开启和关闭 spring_Spring之定时任务实践
Java下的定时任务实现有Timer,Spring,QuartZ等,这里我们介绍Spring中定时任务的应用,其通过 @Scheduled 注解即可轻松实现 概述 Spring 的定时任务可以支持各种 ...
- SpringBoot中的定时任务的同步与异步
SpringBoot中的定时任务的同步与异步你确定真的知道? 授人以渔 Java领域;架构知识;面试心得;互联网行业最新资讯 定时任务调度功能在我们的开发中是非常常见的,随便举几个例子:定时清除一些过 ...
- 秒杀的定时任务开启 、 将秒杀商品存入redis、秒杀商品 下单进入订单队列(未支付)、异步实现下单
秒杀的定时任务开启 ⼀会⼉我们采⽤Spring的定时任务定时将符合参与秒杀的商品查询出来再存⼊到Redis缓存,所以这⾥需要使⽤到定时任务 这⾥我们了解下spring boot定时任务相关的配置,配置 ...
- CentOS6.7防火墙(Iptables)的开启与关闭
Linux防火墙(iptables)的开启与关闭 . Linux中的防火墙主要是对iptables的设置和管理. 1. Linux防火墙(Iptables)重启系统生效 开启: chkconfig i ...
- 02全志r58平台Android4.4.4下关闭内核中的CPU的开启关闭提示
02全志r58平台Android4.4.4下关闭内核中的CPU的开启关闭提示 2017/8/18 13:53 版本:V1.0 开发板:SC5806(全志R58平台) SDK:android4.4.4 ...
- 通过init.rc中的property实现动态控制service的开启与关闭
点击打开链接 根据前一篇博客中的方法描述,我在当前正在开发的android project中进行了相应的代码实现,主要是有两处代码需要修改添加: 第一部分:init.rc 关于init.rc的作用在这 ...
最新文章
- 未来的设计:我们正在进入“计算设计”时代
- mysql case when 去重_【Mysql】 case ... when ... 用法
- MySQL建立多选一列表_如何实现自定义列表的多个item,的单选或多选
- mysql做乘法运算溢出_乘法溢出及对策
- linux ls 命令
- sharding-jdbc水平分库与垂直分库
- ONENET平台简介及简单的接入方法
- 无锡给的sql excel转换
- spring+springmvc+kafka分布式消息中间件集成方案
- PHP (20140510)深入浅出 JavaScript 变量、作用域和内存 v 0.5
- UML统一建模语言——类图、时序图
- vue3中lottie动画的实现
- 精益生产管理中如何进行库存成本控制?
- Java中线程同步锁和互斥锁有啥区别?看完你还是一脸懵逼?
- 天线要设计为四分之一波长的原因
- 计算机键盘灯光怎么关闭,笔记本怎么关键盘的灯_笔记本电脑关闭键盘背光的步骤-win7之家...
- c语言编程TLC2543AD采集,51单片机驱动12位AD转换TLC2543电路图+程序
- 《星际穿越》初解析——一部空前绝后的史诗科学巨作
- ie11对html5支持度,html5最新浏览器支持程度比较
- 基于HFS快速搭建HTTP文件服务器
热门文章
- “半价买2080Ti”,英伟达发布RTX 30系列显卡,性能翻倍价格更低,网友高呼“NVIDIA YES”...
- 红警1开源放出源码,4K高清重制版登顶Steam畅销榜!网友:青春回来了
- 盘点当下大热的 7 大 Github 机器学习『创新』项目
- 10 年前被删的初恋,凌晨 1 点突然加我…
- Scrapyd部署Scrapy框架项目
- MATLAB_图形学_形态学课程II
- 基于 OpenCV 和 OpenPose 的棒球挥杆人体姿势估计
- 年底了,没啥好送的,送个1T移动硬盘吧~
- 算法工程师面试必考项:二叉树
- OpenCV4 C++学习 必备基础语法知识二