今天和大家分享下Spring Task这个知识点,主要通过下面6个点来展开描述,希望能够帮助到大家。

1、什么是定时任务

2、入门案例

3、Corn表达式

4、Corn实战案例

5、@Scheduled

6、多线程任务

1、什么是定时任务

定时任务是系统在特定时间执行一段代码。

定时任务的实现主要有以下几种方式:

  • Java自带的java.util.Timer类。它允许调度一个java.util.TimerTask任务,使用这种方式可以让程序按照某一个频度执行,但不能在指定时间运行,一般运用较少。
  • Quartz。是一个功能比较强大的调度器,可以让程序在执行时间执行,也可以按照某个频度执行,配置起来有点复杂。
  • Spring3.0以后自带Spring Task。可以看成一个轻量级的Quartz,

2、入门案例

1、创建SpringBoot项目在启动类开启定时任务@EnableScheduling

@SpringBootApplication
@EnableScheduling
public class SpringtaskdemoApplication { public static void main(String[] args) {
SpringApplication.run(SpringtaskdemoApplication.class, args);
} }
//每秒都执行一次
@Scheduled(cron = "* * * * * *")
public void test(){
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
System.out.println(format.format(new Date()));
}

3、Corn表达式

Spring Task 依靠Corn表达式配置定时规则,Corn表达式是一个字符串,分为6或7个域。每个域代表一个含义,以空格隔开,有如下两种语法格式:

1、秒 分 时 每月第几天 月份 周几 年份

2、秒 分 时 每月第几天 月份 周几

3.1 秒

Seconds(秒)域可以出现,- * /0-59的整数

  • *:表示匹配该域的任意值,在Seconds域中使用 * 表示每秒钟都会出发

  • ,:表示列出枚举值,在Seconds域中使用5,20表示在5秒和20秒各触发一次

  • -:表示范围,在secondes域使用5-20,表示从5秒到20秒每秒触发一次

  • /:表示起始时间开始触发,然后每隔固定时间触发一次,在secondes域中使用5/20,表示第5秒触发一次,25秒、45秒各触发一次。

3.2 分、时

以上四个字符在minutes和Hours域都可以出现。分钟整数为0-59,小时整数为0-23

3.3 日期

DayofMonty(日期):域中可以出现,- * / ? L W C 八个字符,以及1-31的整数。

  • c:表示和当前日期相关联,如果在该域使用5c ,则在执行当天的5日后执行,且每月的那天都会执行。比如执行日是10号,则每月的15号都会触发。
  • L:表示最后,在该域使用L,表示每月的最后一天触发;
  • W:表示工作日,在该域用15W,表示在最接近本月第15天的工作日出发,如果15号是周六则14号触发,如果15号是周日则16号出发,如果15号是周二,则15号触发。 注:该用法只会在当前月计算,不会到下月触发,比如在DayofMonth域用31W,31号是周日,那么在29号触发,而不是下月1号。
  • 在DayofMonth域用LW,表示这个月的最后一个工作日触发。

3.4 月份

Month(月份):域中可出现,- * / 四个字符,以及1-12的整数或JAN-DEC的单词缩写

3.5 星期

DayofWeek(星期):可出现,- * / ? L # C 八个字符,以及1-7的整数或SUN-SAT单词的缩写,1代表星期天,7代表周六

  • c:在DayofWeek域使用2c,表示在启动日后的2天后触发,且每周的那天都会触发,如在周一启动,那么每周三都会触发;
  • L:L表示一周的最后一天(周六)触发,如果使用5L,表示在一个月的最后一个周四触发
  • :用来执行具体的周数,#前面代表星期几,#后面代表一个月的第几周。如5#3表示一个月第三周的星期四

  • ?:在无法确定是哪一天时使用。用于DayofMonth和DayofWeek域。如每个21号零点触发1次,此时无法确定21号是周几,就写 0 0 0 21 * ?

3.6 年份

Year(年份):,- * / 四个字符,以及 1970~2099的整肃,该域可以省略,表示每年都会触发。

4、Corn实战案例

每间隔5分钟触发一次 :0 0/5 * * * *
每小时触发一次 0 0 * * * *
每天7:30触发 0 30 7 * * *
每周一到周五早上6:30触发 0 30 6 ? * 2-6
每月最后一天早上10点触发 0 0 10 L * ?
每月最后一个工作日的18:30分触发 0 30 18 LW * ?
2030年8月每个星期六和星期日早上10触发 0 0 10 ? 8 7,1 2030
每天10点、12点、14点触发 0 0 10,12,14 * * *
朝九晚五工作日内每半小时触发一次 0 0/30 9-17 W * ? 每周三中午12点触发一次 0 0 12 ? * 4
每天12点触发一次 0 0 12 * * *
每天14点到14:59每分钟触发一次 0 * 14 * * *
每天14点到14:59每5分钟触发一次 0 0/5 14 * * *
每天14点到14:05每分钟触发一次 0 0-5 14 * * *
每月15日上午10:15触发 0 15 10 15 * ?
每月最后一天的上午10:15触发 0 15 10 L * ?
每月的第三个星期五上午10;15触发 0 15 10 ? * 6#3

5、Spring Tash @Scheduled

@Scheduled指定方法定时执行

@Scheduled写在方法上方,指定该方法定时执行,常用参数如下:

  • cron :cron制定方法执行的时间规则
  • fixedDelay :任务立即执行,之后每隔多久就执行一次,单位是毫秒,上次任务结束后计算下次执行的时间
//立即执行,任务结束后每5秒执行一次
@Scheduled(fixedDelay = 5000)
public void task2() throws InterruptedException {
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
Thread.sleep(1000);
System.out.println(format.format(new Date())); }
  • fixedRate:任务立即执行,之后每隔多久就执行一次,单位毫秒,上次任务开始后开始计时
//立即执行,任务开始后每5秒执行一次
@Scheduled(fixedRate = 5000)
public void task3() throws InterruptedException {
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
Thread.sleep(1000);
System.out.println(format.format(new Date())); }
  • initialDelay:项目启动后不马上执行定时器,根据initialDelay 延时执行
//项目启动3s后,之后每5s执行一次
@Scheduled(fixedRate = 5000,initialDelay = 3000)
public void task4() throws InterruptedException {
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
Thread.sleep(1000);
System.out.println(format.format(new Date()));
}

6、Spring Task 多线程任务

Spring Task定时器默认是单线程的,如果项目中使用多个定时器,使用一个线程会造成效率低下如:

@Scheduled(cron = "* * * * * *")
public void task5() throws InterruptedException {
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
Thread.sleep(5000);
System.out.println(format.format(new Date())+Thread.currentThread().getId()+"线程任务1");
}
@Scheduled(cron = "* * * * * *")
public void task6() throws InterruptedException {
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
Thread.sleep(5000);
System.out.println(format.format(new Date())+Thread.currentThread().getId()+"线程任务2");
}

解决这个问题我们可以创建一个线程池。

@Configuration
public class SchedulingConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
//创建线程池
taskRegistrar.setScheduler(Executors.newScheduledThreadPool(5));
}
}

欢迎转载,转载请注明原文出处

个人公众号 :hellotqq,欢迎关注交流与您共同成长!

一文搞定Spring Task的更多相关文章

  1. 一文搞定Spring Boot + Vue 项目在Linux Mysql环境的部署(强烈建议收藏)

    本文介绍Spring Boot.Vue .Vue Element编写的项目,在Linux下的部署,系统采用Mysql数据库.按照本文进行项目部署,不迷路. 1. 前言 典型的软件开发,经过" ...

  2. 一文搞定 Spring Data JPA

    Spring Data JPA 是在 JPA 规范的基础上进行进一步封装的产物,和之前的 JDBC.slf4j 这些一样,只定义了一系列的接口.具体在使用的过程中,一般接入的是 Hibernate 的 ...

  3. 一文搞定 Spring事务

    Spring 事务 上文 使用SpringJDBC 1.JDBC事务控制 ​ 不管你现在使用的是那一种ORM开发框架,只要你的核心是JDBC,那么所有的事务处理都是围绕着JDBC开展的,而JDBC之中 ...

  4. 一文搞定 SonarQube 接入 C#(.NET) 代码质量分析

    1. 前言 C#语言接入Sonar代码静态扫描相较于Java.Python来说,相对麻烦一些.Sonar检测C#代码时需要预先编译,而且C#代码必须用MSbuid进行编译,如果需要使用SonarQub ...

  5. 3步轻松搞定Spring Boot缓存

    作者:谭朝红 前言 本次内容主要介绍基于Ehcache 3.0来快速实现Spring Boot应用程序的数据缓存功能.在Spring Boot应用程序中,我们可以通过Spring Caching来快速 ...

  6. 【项目实践】一文带你搞定Spring Security + JWT

    以项目驱动学习,以实践检验真知 前言 关于认证和授权,R之前已经写了两篇文章: [项目实践]在用安全框架前,我想先让你手撸一个登陆认证 [项目实践]一文带你搞定页面权限.按钮权限以及数据权限 在这两篇 ...

  7. 一文搞定MySQL的事务和隔离级别

    一.事务简介 事务是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成. 一个数据库事务通常包含了一个序列的对数据库的读/写操作.它的存在包含有以下两个目的: 为数据库操作序列提供 ...

  8. 不用找了,300 分钟帮你搞定 Spring Cloud!

    最近几年,微服务架构一跃成为 IT 领域炙手可热的话题,大量一线互联网公司因为庞大的业务体量和业务需求,纷纷投入了微服务架构的建设中,像阿里巴巴.百度.美团等大厂,很早就已经开始了微服务的实践和应用. ...

  9. 一文搞定scrapy爬取众多知名技术博客文章保存到本地数据库,包含:cnblog、csdn、51cto、itpub、jobbole、oschina等

    本文旨在通过爬取一系列博客网站技术文章的实践,介绍一下scrapy这个python语言中强大的整站爬虫框架的使用.各位童鞋可不要用来干坏事哦,这些技术博客平台也是为了让我们大家更方便的交流.学习.提高 ...

  10. Spring Data Redis 详解及实战一文搞定

    SDR - Spring Data Redis的简称. Spring Data Redis提供了从Spring应用程序轻松配置和访问Redis的功能.它提供了与商店互动的低级别和高级别抽象,使用户免受 ...

随机推荐

  1. Kafka之工作流程分析

    Kafka之工作流程分析 kafka核心组成 一.Kafka生产过程分析 1.1 写入方式 producer采用推(push)模式将消息发布到broker,每条消息都被追加(append)到分区(pa ...

  2. java中list集合怎么判断是否为空

    首先看下面代码 @RequestMapping("/getCatlist") public String getCatlist(HttpSession session,HttpSe ...

  3. resutful的使用和增强版的swagger2

    1.REST的特征 统一接口:客户和服务器之间通信的方法必须统一,RESUTFUL风格的数据元操作CRUD分别对应HTTP方法----GET用来获取数据源,POST用来新建资源,PUT用来更新资源,, ...

  4. Springboot JSON 转换:Jackson篇

    本案例基于 Springboot 2.5.7 单元测试场景下进行 <!-- SpringMVC默认使用Jacson,只需要引用web启动器即可,无序单独引用Jackson --> < ...

  5. Oracle数据库PLSQL编程和存储过程

    一.PLSQL编程 1.1.使用PLSQL实现 Hello world! 1 -- Created on 2022/8/22 by ADMINISTRATOR 2 declare 3 -- 这是申明变 ...

  6. visual studio插件开发-Menu

    工欲善其事,必先利其器,作为程序员我们很大部分时间在和ide打交道,好的插件可以大大提高我们的编程效率,我开发过几个vs插件来解决一键生成dbmodels,快速部署到服务器,总结下来最关键的还是对于M ...

  7. Python 多重继承时metaclass conflict问题解决与原理探究

    背景 最近有一个需求需要自定义一个多继承abc.ABC与django.contrib.admin.ModelAdmin两个父类的抽象子类,方便不同模块复用大部分代码,同时强制必须实现所有抽象方法,没想 ...

  8. 华为开发者大会HDC2022:HMS Core 持续创新,与开发者共创美好数智生活

    11月4日,华为开发者大会HDC2022在东莞松山湖拉开帷幕.HMS Core在本次大会上带来了包括音频编辑服务的高拟真歌声合成技术.视频编辑服务的智能提取精彩瞬间功能.3D Engine超大规模数字 ...

  9. 畅联新增插件:新增依爱NB烟感

    双美接入,C++版,就是解析Json时稍微有点问题,依爱这边的Json格式,Value字段竟然是单引号....呵呵,反正也解决了. 备注一下:电信模式,AEP平台模式.

  10. Python学习之实例3

    一.文字读取并打印拼接字符串 1 with open('G:\python\char.txt') as f: #使用open()函数以只读模式打开文件 2 s=f.read() #使用read()方法 ...