【SpingBoot定时任务】Spring自带@Scheduled、异步多线程@Async、quartz框架 定时任务示例

news2024/11/25 12:52:01

文章目录

    • springboot定时任务
      • 1、基于注解(@Scheduled)
      • 2、异步多线程使用定时任务
      • 3、使用quartz实现定时任务
        • 使用Springboot整合Quartz定时任务框架

springboot定时任务

在springboot环境中,实现定时任务有两种方案:

  • 使用 Spring 自带的定时任务处理器 @Scheduled 注解。Spring Boot 源自 Spring+SpringMVC ,因此天然具备这两个 Spring 中的定时任务实现策略
  • 使用第三方框架 Quartz

@EnableScheduling

1、基于注解(@Scheduled)

/**
 * 定时任务
 */
@Configuration      // 1.主要用于标记配置类,兼备Component的效果。
@EnableScheduling   // 2.开启定时任务
public class StaticScheduleTask {

    //3.添加定时任务  每隔5秒调用一次
    @Scheduled(cron = "0/5 * * * * ?")
    public void configureTasks() {
        System.err.println("执行静态定时任务时间: " + LocalDateTime.now());
    }
}

在这里插入图片描述

cron = [秒] [分] [小时] [日] [月] [周] [年]
注意:

  • 在周中1表示周日,2才表示周一,以此类推,7表示周六。
  • 在cron表达式中不区分大小写,即sun和SUN等价。
  • 月份中的日期和星期可能会起冲突,因此在配置时这两个得有一个是 ?
  • 此处给大家提供一个cron表达式生成器https://www.matools.com/cron/
序号说明是否必填允许填写的值允许的通配符
10-59, - * /
20-59, - * /
30-23, - * /
41-31, - * ? / L W C
51-12或JAN~DEC, - * /
61-7 或 SUN/MON/TUE/WED/THU/FRI/SAT, - * ? / L C #
7空或1970-2099, - * /

规则:

  • ?:表示不指定值,即不关心某个字段的取值时使用。需要注意的是,月份中的日期和星期可能会起冲突,因此在配置时这两个得有一个是?
  • *:表示所有值,例如:在秒的字段上设置 *,表示每一秒都会触发
  • ,:用来分开多个值,例如在周字段上设置 “MON,WED,FRI” 表示周一,周三和周五触发
  • -:表示区间,例如在秒上设置 “10-12”,表示 10,11,12秒都会触发
  • /:用于递增触发,如在秒上面设置"5/15" 表示从5秒开始,每增15秒触发(5,20,35,50)
  • #:序号(表示每月的第几个周几),例如在周字段上设置"6#3"表示在每月的第三个周六,(用 在母亲节和父亲节再合适不过了)周字段的设置,若使用英文字母是不区分大小写的 ,即 MON 与mon相同
  • L:表示最后的意思。在日字段设置上,表示当月的最后一天(依据当前月份,如果是二月还会自动判断是否是润年),在周字段上表示星期六,相当于"7"或"SAT"(注意周日算是第一天)。如果在"L"前加上数字,则表示该数据的最后一个。例如在周字段上设置"6L"这样的格式,则表示"本月最后一个星期五"
  • W:表示离指定日期的最近工作日(周一至周五),例如在日字段上设置"15W",表示离每月15号最近的那个工作日触发。如果15号正好是周六,则找最近的周五(14号)触发, 如果15号是周未,则找最近的下周一(16号)触发,如果15号正好在工作日(周一至周五),则就在该天触发。如果指定格式为 “1W”,它则表示每月1号往后最近的工作日触发。如果1号正是周六,则将在3号下周一触发。(注,“W"前只能设置具体的数字,不允许区间”-“)
    L 和 W 可以一组合使用。如果在日字段上设置"LW”,则表示在本月的最后一个工作日触发


2、异步多线程使用定时任务

【同时执行多个定时任务,会出现高并发问题(同一数据来不及更新),所以就存在创建多线程定时任务。】
示例一:

@Configuration      // 1.主要用于标记配置类,兼备Component的效果。
@EnableScheduling   // 2.开启定时任务
@EnableAsync        // 4.开启多线程
public class SaticScheduleTask {
    
    //3.添加定时任务
    @Scheduled(cron = "0/5 * * * * ?")
    @Async //异步方法  异步调用  默认为同步
    //@Transactional //添加事务
    public void configureTasks() {
    	//每次执行会产生一个新的线程
        System.err.println(Thread.currentThread.getName()+"执行静态定时任务时间: " + LocalDateTime.now());
    }
}

在这里插入图片描述


示例二:

@Component
@EnableScheduling   // 1.开启定时任务
@EnableAsync        // 2.开启多线程
public class MultithreadScheduleTask {

        @Async
        @Scheduled(fixedDelay = 1000)  //间隔1秒
        public void first() throws InterruptedException {
            System.out.println("第一个定时任务开始 : " + LocalDateTime.now().toLocalTime() + "\r\n线程 : " + Thread.currentThread().getName());
            System.out.println();
            Thread.sleep(1000 * 10);
        }
 
        @Async
        @Scheduled(fixedDelay = 2000)   //间隔2秒
        public void second() {
            System.out.println("第二个定时任务开始 : " + LocalDateTime.now().toLocalTime() + "\r\n线程 : " + Thread.currentThread().getName());
            System.out.println();
        }
    }

第一个和第二个定时任务互不影响;并且,由于开启了多线程,第一个任务的执行时间也不受其本身执行时间的限制,所以需要注意可能会出现重复操作导致数据异常。
在这里插入图片描述

根据Spring的文档说明,默认采用的是单线程的模式的。所以在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的。

那么当多个任务的执行势必会相互影响。例如,如果A任务执行时间比较长,那么B任务必须等到A任务执行完毕后才会启动执行。又如在处理与第三方系统交互的时候,容易造成响应迟缓的情况,之前大部分都是使用多线程来完成此类任务,其实,在spring3.x之后,已经内置了@Async来完美解决这个问题。

3、使用quartz实现定时任务

官网:http://www.quartz-scheduler.org/
使用一种新的框架,自然要引入jar包,版本就随springboot

<!--核心jar包-->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starterquartz</artifactId>
</dependency>

使用Springboot整合Quartz定时任务框架

  • 任务Job:job就是你想要实现的任务类,每一个job必须实现org.quartz.job接口。
  • 触发器Trigger: Trigger为你执行任务的触发器,比如你想每天定时某点发送一份统计邮件,Trigger将会设置某点进行执行该任务。
  • 调度器Scheduler:Scheduler为任务的调度器,它会将任务job及触发器Trigger整合起来,负责基于Trigger设定的时间来执行Job

示例:每隔两秒发一次任务,发5次

jar包

<!--quartz核心包-->
 <dependency>
     <groupId>org.quartz-scheduler</groupId>
     <artifactId>quartz</artifactId>
     <version>2.3.2</version>
     <exclusions>
         <exclusion>
             <artifactId>slf4j-api</artifactId>
             <groupId>org.slf4j</groupId>
         </exclusion>
     </exclusions>
 </dependency>
<!--工具-->
<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz-jobs</artifactId>
    <version>2.3.2</version>
</dependency>
<!--slf4j-->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.7</version>
    <!-- <scope>compile</scope>-->
</dependency>
<!--添加Scheduled坐标-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
</dependency>
<!--Spring tx 坐标-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
</dependency>

job任务类:

public class QuartzDemo implements Job {

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("Execute..." + new Date());
    }
}

配置类:配置触发器与任务调度器

/**
 * quartz配置类
 */
@Configuration
public class QuartzConfig {
    /**
     * 1、创建Job对象
     */
    @Bean
    public JobDetailFactoryBean jobDetailFactoryBean(){
        JobDetailFactoryBean factoryBean=new JobDetailFactoryBean();
        //关联我们自己的Job类
        factoryBean.setJobClass(QuartzDemo.class);
        return factoryBean;
    }

    /**
     * 2、创建Trigger对象
     */
    @Bean
    public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
        SimpleTriggerFactoryBean factoryBean=new SimpleTriggerFactoryBean();
        //关联JobDetail对象
        factoryBean.setJobDetail(jobDetailFactoryBean.getObject());
        //该参数表示一个执行的毫秒数
        factoryBean.setRepeatInterval(2000); //每隔2秒执行一次
        //重复次数
        factoryBean.setRepeatCount(5);
        return factoryBean;
    }

    /**
     * 3、创建Scheduler
     */
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(SimpleTriggerFactoryBean simpleTriggerFactoryBean){
        SchedulerFactoryBean factoryBean=new SchedulerFactoryBean();
        //关联trigger
        factoryBean.setTriggers(simpleTriggerFactoryBean.getObject());
        return factoryBean;
    }
}

项目的启动类启动运行:

@SpringBootApplication
@EnableScheduling
public class SpringBootCrontabApplication extends SpringBootServletInitializer {
   	public static void main(String[] args) {
        SpringApplication.run(SpringBootCrontabApplication.class, args);
    }
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/57998.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

程序员,阿里 P8java 大神讲的 Spring 大家族原理汇总,你确定不看?

之前分享的 java 核心面试知识点已经花了三篇文章的篇幅讲完了 java 多线程并发。作为程序员来讲&#xff0c;多线程并发要学的东西确实挺多的&#xff0c;那天跟阿里程序员朋友聊天的时候&#xff0c;被绝对技术碾压了&#xff0c;多线程并发里的内容&#xff0c;能够全面的讲…

太硬核!用大数据技术预测足球胜率

点个关注&#x1f446;跟腾讯工程师学技术引言| 足球作为世界第一运动&#xff0c;充满了速度和力量的结果&#xff0c;团队与谋略的对抗。人们也说&#xff0c;足球是圆的&#xff0c;恰恰也表明了足球比赛的不可预知性&#xff0c;一切结果都皆有可能。强如巴萨&#xff0c;也…

JavaScript 简单介绍和使用

JS 环境搭建 基本语法&#xff1a; 注释&#xff1a; // 单行注释 /* 多行注释 */ 输入输出语句 // 输入输出语句 document.getElementById("btn").onclick function(){// 输入语句var message prompt("输入信息")var insure confirm("是否确认…

FrameWork之旅 -- 源代码主要目录结构

本系列的阅读&#xff0c;前提你是一个Android开发者&#xff0c;而且是一个app开发&#xff0c;并且有一定的工作经验。本系列的学习&#xff0c;不会每个细节都说明&#xff0c;会把有“看点”的地方加以说明。 我们开发或者熟悉任何软件项目&#xff0c;都要了解包名结构或…

Python学习基础笔记十五——命名空间和作用域

从Python解释器开始执行之后&#xff0c;就在内存中开辟了一个空间。 每当遇到一个变量的时候&#xff0c;就把变量名和值的对应关系记录下来。 但是当遇到函数定义的时候解释器只是象征性地将函数名读入内存&#xff0c;表示知道这个函数的存在了&#xff0c;至于函数内部的变…

Vue 插槽(slot)使用

1 为什么使用slot 组件的插槽 组件的插槽是为了让我们封装的组件更加具有扩展性。 让使用者可以决定组件内部一些内容到底展示了什么。 举例&#xff1a; 移动开发中&#xff0c;几乎每个页面都有导航栏 导航栏我们会分装成一个插件&#xff0c;比如nav-bar组件 一旦有了…

vue父子组件间数据的双向绑定

在vue中数据的流向通常是单向的&#xff0c;但是实际开发中&#xff0c;存在父子组件都需要对父组件值进行更新的情况&#xff0c;vue提供了两种方法实现数据的双向绑定&#xff1a; 1、使用v-model指令 在父组件上 v-model 会利用子组件名为 value 的 prop 和名为 input 的…

第5 部分 EIGRP

目录 5.1 EIGRP 概述 5.2 实验1&#xff1a;EIGRP 基本配置 1. 实验目的 2. 实验拓扑 3. 实验步骤 4. 实验调试 &#xff08;1&#xff09;show ip route &#xff08;2&#xff09;show ip protocols​编辑 &#xff08;3&#xff09;show ip eigrp neighbors &#…

[激光原理与应用-31]:典型激光器 -3- 光纤激光器

目录 第1章 光纤激光器概述 1.1 什么是光纤激光器 1.2 应用 1.3 光纤激光器的结构组成 1.4 特点 1.5 优势 第2章 光纤激光器的类型 2.1 按照光纤材料的种类进行分类 2.2 按增益介质分类为&#xff1a; 2.3 按谐振腔结构分类 2.4 按光纤结构分类 2.5 按输出激光特性…

基于 ARM + FPGA 的 EtherCAT 主站设计及实现

为解决实时工业以太网协议 EtherCAT 应用于嵌入式主站控制器所产生的实时性和稳定性等问题&#xff0c;首先研究了 EtherCAT 主站控制器在 EtherCAT 网络控制系统中的功能需求&#xff0c;分析并提出了实现嵌入式 EtherCAT 主站的架构&#xff0c;然后针对上述架构设计了基于 A…

补知识点:Feign、Nacos配置中心(命名空间、配置分组)

一、Feign的应用 和前面的Feign笔记是一样的&#xff0c;不过这里更深刻的理解一下 使用Feign的整体步骤就分为以下几个步骤&#xff1a; 1、引入open-feign依赖坐标 2、编写一个接口&#xff0c;告诉springCloud这个接口需要调用远程服务 3、在启动类当中开启远程调用功能注解…

[附源码]计算机毕业设计JAVA学生宿舍管理系统

[附源码]计算机毕业设计JAVA学生宿舍管理系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybati…

06_openstack之创建云主机和常见错误

目录 一、环境准备 二、创建云主机 三、常见错误 1、创建云主机时&#xff0c;主机状态显示“错误” 2、云主机控制台无法访问&#xff0c;报错1006 3、云主机创建错误&#xff0c;提示“找不到有效主机&#xff0c;原因是没有足够的主机可用” 一、环境准备 部署openst…

什么样的架构师修炼之道文档,能帮助大家修炼成为出色的架构师?

前言 时间飞逝&#xff0c;转眼间毕业七年多&#xff0c;从事 Java 开发也六年了。我在想&#xff0c;也是时候将自己的 Java 整理成一套体系。 这一次的知识体系面试题涉及到 Java 知识部分、性能优化、微服务、并发编程、开源框架、分布式等多个方面的知识点。 写这一套 Ja…

Java基于springboot+vue的汽车销售购物商城系统

前言背景 随着我国的经济发展&#xff0c;人们的生活水平也有了一定程度的提高&#xff0c;汽车也逐渐由以前的奢侈品变成了很多人必须的代步工具&#xff0c;然而我国的很多汽车销售企业都没有成套的管理系统&#xff0c;通过我在假期的实习和一定时间的调查研究发现了传统的…

[附源码]Python计算机毕业设计Django教务管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

Js逆向教程18-l参数分解

作者&#xff1a;虚坏叔叔 博客&#xff1a;https://xuhss.com 早餐店不会开到晚上&#xff0c;想吃的人早就来了&#xff01;&#x1f604; Js逆向教程18-l参数分解 一、l参数分解 可以看到l是一个大数组。 里面有很多字节码 V[$_CAIAt(353)](gt[$_CAIAt(218)](o), r[$_CAIA…

【Java基础】· 集合习题详解

写在前面 Hello大家好&#xff0c; 我是【麟-小白】&#xff0c;一位软件工程专业的学生&#xff0c;喜好计算机知识。希望大家能够一起学习进步呀&#xff01;本人是一名在读大学生&#xff0c;专业水平有限&#xff0c;如发现错误或不足之处&#xff0c;请多多指正&#xff0…

如何测试 LoRaWAN 全球频段

To be a sailor of the world, bound for all ports. 做世界的水手&#xff0c;游遍所有的港口。 背景 自 2015 年 LoRa 联盟创建 LoRaWAN 协议&#xff0c;经过 7 年长跑&#xff0c;到 2022 年国际电信联盟 (ITU) 正式批准 LoRaWAN 作为全球标准: ITU-T Y.4480“广域无线网…

一些并查集的题~~判树,连通,带权

目录 A-Wireless Network B-The Suspects C - How Many Tables D - How Many Answers Are Wrong G - Supermarket L - 小希的迷宫 M - Is It A Tree&#xff1f; J - A Bug‘s Life E - 食物链 A-Wireless Network POJ - 2236 ​ 翻译&#xff1a; 东南亚发生了地震…