springBoot定时任务可分为多线程和单线程,而单线程又分为注解形式,接口形式

1.基于注解形式

基于注解@Scheduled默认为单线程,开启多个任务时,任务的执行时机会受上一个任务执行时间的影响。

  1)创建定时器

  使用SpringBoot基于注解来创建定时任务非常简单,只需几行代码便可完成。 代码如下

  

  1. package com.cst.klocwork.service.cron;
  2.  
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.scheduling.annotation.EnableScheduling;
  5. import org.springframework.scheduling.annotation.Scheduled;
  6. import org.springframework.stereotype.Component;
  7.  
  8. import com.cst.util.string.LocalDateTimes;
  9.  
  10. @Component
  11. @Configuration //1.主要用于标记配置类,兼备Component的效果。
  12. @EnableScheduling // 2.开启定时任务
  13. public class Test {
  14. //3.添加定时任务
  15. @Scheduled(cron = "0/5 * * * * ?")
  16. //或直接指定时间间隔,例如:5秒
  17. //@Scheduled(fixedRate=5000)
  18. private void configureTasks() {
  19. f1();
  20. }
  21.  
  22. public void f1() {
  23. System.err.println("执行静态定时任务时间:=== " + LocalDateTimes.nowFormat());
  24. }
  25. }

  Cron表达式参数分别表示:

  • 秒(0~59) 例如0/5表示每5秒
  • 分(0~59)
  • 时(0~23)
  • 日(0~31)的某天,需计算
  • 月(0~11)
  • 周几( 可填1-7 或 SUN/MON/TUE/WED/THU/FRI/SAT)

  @Scheduled:除了支持灵活的参数表达式cron之外,还支持简单的延时操作,例如 fixedDelay ,fixedRate 填写相应的毫秒数即可。

  2)启动测试

  启动springBoot项目,可以看到控制台打印出如下信息:

  

  显然,使用@Scheduled 注解很方便,但缺点是当我们调整了执行周期的时候,需要重启应用才能生效,这多少有些不方便。为了达到实时生效的效果,可以使用接口来完成定时任务。

2.基于接口

  1)导入依赖包:

  1. <parent>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter</artifactId>
  4. <version>2.0.4.RELEASE</version>
  5. </parent>
  6.  
  7. <dependencies>
  8. <dependency><!--添加Web依赖 -->
  9. <groupId>org.springframework.boot</groupId>
  10. <artifactId>spring-boot-starter-web</artifactId>
  11. </dependency>
  12. <dependency><!--添加MySql依赖 -->
  13. <groupId>mysql</groupId>
  14. <artifactId>mysql-connector-java</artifactId>
  15. </dependency>
  16. <dependency><!--添加Mybatis依赖 配置mybatis的一些初始化的东西-->
  17. <groupId>org.mybatis.spring.boot</groupId>
  18. <artifactId>mybatis-spring-boot-starter</artifactId>
  19. <version>1.3.1</version>
  20. </dependency>
  21. <dependency><!-- 添加mybatis依赖 -->
  22. <groupId>org.mybatis</groupId>
  23. <artifactId>mybatis</artifactId>
  24. <version>3.4.5</version>
  25. <scope>compile</scope>
  26. </dependency>
  27. </dependencies>

    2)添加数据库记录:

  1. DROP DATABASE IF EXISTS `socks`;
  2. CREATE DATABASE `socks`;
  3. USE `SOCKS`;
  4. DROP TABLE IF EXISTS `cron`;
  5. CREATE TABLE `cron` (
  6. `cron_id` varchar(30) NOT NULL PRIMARY KEY,
  7. `cron` varchar(30) NOT NULL
  8. );
  9. INSERT INTO `cron` VALUES ('1', '0/5 * * * * ?');

  然后在项目中的application.properties添加数据库的配置

3.创建定时器

  数据库准备好数据之后,我们编写定时任务,注意这里添加的是TriggerTask,目的是循环读取我们在数据库设置好的执行周期,以及执行相关定时任务的内容。
具体代码如下:

bean类:

  1. package com.cst.klocwork.bean.cron;
  2.  
  3. import com.cst.util.bean.IBean;
  4. import lombok.Data;
  5. import lombok.experimental.Accessors;
  6.  
  7. @Accessors(chain = true)
  8. @Data
  9. public class Cron implements IBean{
  10. private static final long serialVersionUID = 1L;
  11. private String cron_id;
  12. private String cron;
  13.  
  14. }

mapper类:

  1. package com.cst.klocwork.bean.cron;
  2. import org.apache.ibatis.annotations.Mapper;
  3. import org.apache.ibatis.annotations.Select;
  4. import org.springframework.stereotype.Component;
  5.  
  6. import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  7.  
  8. @Mapper
  9. @Component
  10. public interface CronMapper extends BaseMapper<Cron>{
  11.  
  12. @Select("select cron from cron where cron_id = '1'")
  13. String getCron();
  14.  
  15. }

 定时器任务类:

  1. package com.cst.klocwork.service.cron;
  2.  
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.context.annotation.Configuration;
  5. import org.springframework.scheduling.annotation.EnableScheduling;
  6. import org.springframework.scheduling.annotation.SchedulingConfigurer;
  7. import org.springframework.scheduling.config.ScheduledTaskRegistrar;
  8. import org.springframework.scheduling.support.CronTrigger;
  9. import org.springframework.stereotype.Component;
  10. import org.springframework.util.StringUtils;
  11.  
  12. import com.cst.klocwork.bean.cron.CronMapper;
  13. import com.cst.util.string.LocalDateTimes;
  14.  
  15. @Component
  16. @Configuration //1.主要用于标记配置类,兼备Component的效果。
  17. @EnableScheduling // 2.开启定时任务
  18. public class DynamicScheduleTask implements SchedulingConfigurer {
  19.  
  20. @Autowired //注入mapper
  21. private CronMapper cronMapper;
  22.  
  23. /**
  24. * 执行定时任务.
  25. */
  26. @Override
  27. public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
  28.  
  29. taskRegistrar.addTriggerTask(
  30. //1.添加任务内容(Runnable)
  31. () -> f1(),
  32. //2.设置执行周期(Trigger)
  33. triggerContext -> {
  34. //2.1 从数据库获取执行周期
  35. String cron = cronMapper.getCron();
  36. //2.2 合法性校验.
  37. if (StringUtils.isEmpty(cron)) {
  38. // Omitted Code ..
  39. }
  40. //2.3 返回执行周期(Date)
  41. return new CronTrigger(cron).nextExecutionTime(triggerContext);
  42. }
  43. );
  44. }
  45.  
  46. public void f1() {
  47. System.err.println("执行动态定时任务: " + LocalDateTimes.nowFormat());
  48. }
  49. }

  4)、启动测试

  启动springBoot项目后,查看控制台,打印时间是我们预期的每10秒一次:

  如果此处想修改运行周期,只需要修改数据库里的时间即可改变运行周期。并且不需要我们重启应用,十分方便。

  注意: 如果在数据库修改时格式出现错误,则定时任务会停止,即使重新修改正确;此时只能重新启动项目才能恢复。

3.多线程定时任务

  基于注解设定多线程定时任务

  1)创建多线程定时任务

  1. //@Component注解用于对那些比较中立的类进行注释;
  2. //相对与在持久层、业务层和控制层分别采用 @Repository、@Service 和 @Controller 对分层中的类进行注释
  3. @Component
  4. @EnableScheduling // 1.开启定时任务
  5. @EnableAsync // 2.开启多线程
  6. public class MultithreadScheduleTask {
  7.  
  8. @Async
  9. @Scheduled(fixedDelay = 1000) //间隔1秒
  10. public void first() throws InterruptedException {
  11. System.out.println("第一个定时任务开始 : " + LocalDateTime.now().toLocalTime() + "\r\n线程 : " + Thread.currentThread().getName());
  12. System.out.println();
  13. Thread.sleep(1000 * 10);
  14. }
  15.  
  16. @Async
  17. @Scheduled(fixedDelay = 2000)
  18. public void second() {
  19. System.out.println("第二个定时任务开始 : " + LocalDateTime.now().toLocalTime() + "\r\n线程 : " + Thread.currentThread().getName());
  20. System.out.println();
  21. }
  22. }

  2)启动springBoot项目后

  查看控制台

  

从控制台可以看出,第一个定时任务和第二个定时任务互不影响;

并且,由于开启了多线程,第一个任务的执行时间也不受其本身执行时间的限制,所以需要注意可能会出现重复操作导致数据异常。

SpringBoot的定时任务的更多相关文章

  1. 玩转SpringBoot之定时任务详解

    序言 使用SpringBoot创建定时任务非常简单,目前主要有以下三种创建方式: 一.基于注解(@Scheduled) 二.基于接口(SchedulingConfigurer) 前者相信大家都很熟悉, ...

  2. SpringBoot 配置定时任务

    SpringBoot启用定时任务,其内部集成了成熟的框架,因此我们可以很简单的使用它. 开启定时任务 @SpringBootApplication //设置扫描的组件的包 @ComponentScan ...

  3. SpringBoot - 添加定时任务

    SpringBoot 添加定时任务 EXample1: import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spri ...

  4. springboot之定时任务

    定时线程 说到定时任务,通常会想到JDK自带的定时线程来执行,定时任务. 回顾一下定时线程池. public static ScheduledExecutorService newScheduledT ...

  5. SpringBoot整合定时任务和异步任务处理 3节课

    1.SpringBoot定时任务schedule讲解   定时任务应用场景: 简介:讲解什么是定时任务和常见定时任务区别 1.常见定时任务 Java自带的java.util.Timer类        ...

  6. 十三、springboot集成定时任务(Scheduling Tasks)

    定时任务(Scheduling Tasks) 在springboot创建定时任务比较简单,只需2步: 1.在程序的入口加上@EnableScheduling注解. 2.在定时方法上加@Schedule ...

  7. SpringBoot创建定时任务

    之前总结过spring+quartz实现定时任务的整合http://www.cnblogs.com/gdpuzxs/p/6663725.html,而springboot创建定时任务则是相当简单. (1 ...

  8. springboot开启定时任务 添加定时任务 推送

    最近在自学Java的springboot框架,要用到定时推送消息.参考了网上的教程,自己调试,终于调好了.下面将网上的教程归纳下,总结复习下.  springboot开启定时任务  在SpringBo ...

  9. (入门SpringBoot)SpringBoot结合定时任务task(十)

    SpringBoot整合定时任务task 使用注解EnableScheduling在启动类上. 定义@Component作为组件被容器扫描. 表达式生成地址:http://cron.qqe2.com ...

  10. SpringBoot整合定时任务和异步任务处理

    SpringBoot定时任务schedule讲解 简介:讲解什么是定时任务和常见定时任务区别 1.常见定时任务 Java自带的java.util.Timer类 timer:配置比较麻烦,时间延后问题, ...

随机推荐

  1. MongoDB与MySQL效率对比

    本文主要通过批量与非批量对比操作的方式介绍MongoDB的bulkWrite()方法的使用.顺带与关系型数据库MySQL进行对比,比较这两种不同类型数据库的效率.如果只是想学习bulkWrite()的 ...

  2. EDG夺冠!用Python分析22.3万条数据:粉丝都疯了!

    一.EDG夺冠信息 11月6日,在英雄联盟总决赛中,EDG战队以3:2战胜韩国队,获得2021年英雄联盟全球总决赛冠军,这个比赛在全网各大平台也是备受瞩目: 1.微博热搜第一名,截止2021-11-1 ...

  3. Unable to unwrap data, invalid status [CLOSED]-服务端webSocket报错

    一.问题由来 现在的项目中在使用webSocket这门技术,主要用来在服务端和客户端进行实时的数据传输,因为需要及时的进行响应,所以才没有使用http请求的方式, 而是使用socket的方式,这样可以 ...

  4. 菜鸡的Java笔记 Eclipse 的使用

    Eclipse 的使用    1. Eclipse 简介    2. Eclipse 中的JDT 的使用    3. Eclipse 中的使用 junit 测试        Eclipse (中文翻 ...

  5. Python变量和数据类型,类型转换

    a.变量的定义 把数据分别用一个简单的名字代表,方便在接下来的程序中引用. 变量就是代表某个数据(值)的名称. 变量就是用来存储数据的,将不同的数据类型存储到内存   b.变量的赋值 变量名= 初始值 ...

  6. linux 系统ssh超时设置

    1.修改client端的etc/ssh/ssh_config添加以下:(在没有权限改server配置的情形下) ServerAliveInterval 60 #client每隔60秒发送一次请求给se ...

  7. Exploring Matrix

    import java.util.Scanner; public class J714 { /** * @taking input from user */ public static void ma ...

  8. 性能压测-压力测试-Apache JMeter安装使用

    http://jmeter.apache.org/download_jmeter.cgi 下载win10得zip文件 在有java环境后进入项目得bin->jmeter.bat 启动 自带国际化 ...

  9. CentOS7部署ceph

    CEPH 简介 不管你是想为云平台提供Ceph 对象存储和/或 Ceph 块设备,还是想部署一个 Ceph 文件系统或者把 Ceph 作为他用,所有 Ceph 存储集群的部署都始于部署一个个 Ceph ...

  10. GWAS分析结果中pvalue/p.ajust为0时如何处理?

    在GWAS分析的结果中,偶尔会遇到到pvalue为0的SNP位点,这时如果直接做曼哈顿或QQ图,会出错,因为log0无意义. 此时,该如何处理? 如果你用的是Plink1.9来做的GWAS,可加一个参 ...