@Scheduled任务调度/定时任务-非分布式
1、功能概述
任务调度就是在规定的时间内执行的任务或者按照固定的频率执行的任务。是非常常见的功能之一。常见的有JDK原生的Timer, ScheduledThreadPoolExecutor以及springboot提供的@Schduled。分布式调度框架如QuartZ、Elasticjob、XXL-JOB、SchedulerX、PowerJob等。
本文主要讲解非分布式环境下的@Scheduled任务调度讲解,以及@Scheduled结合多线程和@Async异步任务的使用。
当然在任务不是很多的情况下@Scheduled也可以结合如Redis的锁机制实现分布式的任务调度,但是还是建议在分布式环境下,使用分布式调度框架如:QuartZ、Elasticjob、XXL-JOB、SchedulerX、PowerJob等。
2、@Scheduled基本使用
2.1、创建springboot工程引入包信息
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.1.6</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.txc</groupId><artifactId>scheduleddemo</artifactId><version>0.0.1-SNAPSHOT</version><name>scheduleddemo</name><description>scheduleddemo</description><properties><java.version>17</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><image><builder>paketobuildpacks/builder-jammy-base:latest</builder></image><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>
2.2、按照固定间隔执行
fixedDelay:按照固定间隔执行,上一个任务的结束到下一个任务的开始间隔。
initialDealay:延迟启动,启动之后指定时间再执行调度任务
@EnableScheduling:开启任务调度,写在类上只开启当前类中的任务调度,如果写在启动类上则开启项目中的所有任务调度。
@Slf4j
//加载类型开启类中,加载启动类上,开启整个项目
@EnableScheduling //是否开启
@Component
public class MyScheduled {@Scheduled(fixedDelay = 3000,initialDelay = 3000)public void process(){log.info("=====process执行========"+ LocalDateTime.now());}
}
结果分析:
从输出结果中可以看出,程序每隔3s执行一次
2.3、按照固定频率执行任务
说明1:fixedRate:按照固定频率执行任务,如每三秒执行一次,上一个任务下次任务的开始,由于此时是单线程,下一个任务开始需要等上一个任务结束。
说明2:我们通过Thread.sleep(5000)设置任务执行需要2s时间
@Slf4j
//加载类型开启类中,加载启动类上,开启整个项目
@EnableScheduling //是否开启
@Component
public class MyScheduled {
@Scheduled(fixedRate = 3000,initialDelay = 3000)
public void process() throws InterruptedException {
log.info("=====process执行fixedRate开始========"+ LocalDateTime.now());Thread.sleep(2000);log.info("=====process执行fixedRate结束========"+ LocalDateTime.now());}
}
结果分析:
从结果中可以看出由于设置process执行的时间为2s钟,process按照固定的频率(3s)每3s执行一次,第一次开始是22:19:22,第二次开始是22:19:25
2.4、按照固定频率执行任务
说明1:fixedRate:按照固定频率执行任务,如每三秒执行一次,上一个任务下次任务的开始,由于此时是单线程,下一个任务开始需要等上一个任务结束。
说明2:我们通过Thread.sleep(5000)设置任务执行需要5s时间
@Slf4j
//加载类型开启类中,加载启动类上,开启整个项目
@EnableScheduling //是否开启
@Component
public class MyScheduled {
@Scheduled(fixedRate = 3000,initialDelay = 3000)
public void process() throws InterruptedException {log.info("=====process执行fixedRate开始========"+ LocalDateTime.now());Thread.sleep(5000);log.info("=====process执行fixedRate结束========"+ LocalDateTime.now());}
}
结果分析:
从结果可以看出:虽然设置固定的频率是3s,但是由于在单线程情况下下次任务的开启需要等待上一个任务的结束,第一次任务开始时间为22:17:43,第二次任务开启时间为22:17:48中间间隔了5s钟。
2.5、通过公式设置定时任务
cron:可以通过特性的公式设定定时任务,任务生成网站https://cron.qqe2.com/
如:可以设置每周三下午五点执行,每月的月尾执行一次等。
如上图生成的语法表示:每分钟的前五秒执行process
@Slf4j
//加载类型开启类中,加载启动类上,开启整个项目
@EnableScheduling //是否开启
@Component
public class MyScheduled {
@Scheduled(cron ="0,1,2,3,4 * * * * ? ")
public void process() throws InterruptedException {log.info("=====process执行fixedRate开始========"+ LocalDateTime.now());Thread.sleep(5000);log.info("=====process执行fixedRate结束========"+ LocalDateTime.now());}
}
结果分析:
从图中可以看出每每分钟开始的时候执行,五秒后结束。
3、@Scheduled与多线程
加入多线程的目的是为了程序执行的效率能够提高。但是在设置多线程的时候,不能开辟过多的线程,因为线程资源非常的消耗cpu资源,必要的时候需要使用分布式任务调度。
3.1、非多线程的情况
理论上当process1结束的时候,下次process1启动的时候需要等待process2执行结束,否则1不能启动,应该这个时候依旧是单线程。
@Slf4j
//加载类型开启类中,加载启动类上,开启整个项目
@EnableScheduling //是否开启
@Component
public class MyScheduled {
@Scheduled(fixedDelay = 3000)
public void process1() throws InterruptedException {
log.info("=====process1执行开始========"+ LocalDateTime.now());Thread.sleep(5000);log.info("=====process1执行结束========"+ LocalDateTime.now());}
@Scheduled(fixedDelay = 3000)
public void process2() throws InterruptedException {log.info("=====process2执行开始========"+ LocalDateTime.now());Thread.sleep(5000);log.info("=====process2执行结束========"+ LocalDateTime.now());}
}
结果分析:
从输出结果可以看出process2的开始是等到process1结束后才执行的。
3.2、多线程的情况
在启动类中定义线程池。值不需要设置太大,现成对cpu资源消耗大,搞不好容易让系统宕机。
设置多线程后直接启动程序,继续观看process1和process2的输出情况。
package com.txc.scheduleddemo;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;@SpringBootApplication
public class ScheduleddemoApplication {public static void main(String[] args) {SpringApplication.run(ScheduleddemoApplication.class, args);}@Beanpublic TaskScheduler taskScheduler(){ThreadPoolTaskScheduler taskScheduler=new ThreadPoolTaskScheduler();//设置线程池中线程的数量//多线程对cpu资源消耗较大,值不能太大。taskScheduler.setPoolSize(5);return taskScheduler;}}
结果分析:
process1和process2使用的是不同的线程,一个线程为taskSheduler-1,一个线程为taskSheduler-2。
而且process1和process2是同时启动的,没有出现相互等待的情况,因为现在使用的是多线程的情况。
4、@Scheduled与@ Async异步任务
在上面的案例中虽然process1和process2同时执行了,没有出现相互等待的情况。但是第二次process1和process2执行依旧是等待程序5s结束后再等待3是执行。
name如何能够实现即使process1执行时间为5s,但是下一次process1的启动依旧是3s后。而不是当前的8是后。这就可以使用异步任务@Async。当然复杂的异步任务还是建议使用如MQ技术。
注意点:@Async的使用需要写在单独的一个类中,不能与当前调用业务写在一起,否则不生效。
完全不会使用@Async看如下博客:
https://blog.csdn.net/tangshiyilang/article/details/129440283
4.1、创建异步任务类及异步方法
@Component
public class AsyncTaskScheduled {@Async//那个方法需要使用异步调用,就使用该注解public void asyncMethod() {try{Thread.sleep(6000);//模拟异步执行业务的时间}catch (Exception e){System.out.println(e.getStackTrace());}}
}
4.2、需要再启动类上开启异步任务
@EnableAsync:开启异步任务调度
@SpringBootApplication
@EnableAsync
public class ScheduleddemoApplication {public static void main(String[] args) {SpringApplication.run(ScheduleddemoApplication.class, args);}@Beanpublic TaskScheduler taskScheduler(){ThreadPoolTaskScheduler taskScheduler=new ThreadPoolTaskScheduler();//设置线程池中线程的数量//多线程对cpu资源消耗较大,值不能太大。taskScheduler.setPoolSize(10);return taskScheduler;}}
4.3、创建process3和process4方法
process3和process3与之前的process1和process2方法一样都是基于多线程操作。
@Slf4j
//加载类型开启类中,加载启动类上,开启整个项目
@EnableScheduling //是否开启
@Component
public class MyScheduled {
@Autowired
AsyncTaskScheduled asyncTaskScheduled;
@Scheduled(fixedDelay = 3000)
public void process3() throws InterruptedException {
log.info("=====process3执行开始========"+ LocalDateTime.now());asyncTaskScheduled.asyncMethod();log.info("=====process3执行结束========"+ LocalDateTime.now());}
@Scheduled(fixedDelay = 3000)
public void process4() throws InterruptedException {log.info("=====process4执行开始========"+ LocalDateTime.now());asyncTaskScheduled.asyncMethod();log.info("=====process4执行结束========"+ LocalDateTime.now());}
}
结果分析:
从结果可以看出,虽然异步任务执行的时间为6s,但是process4第一次开始和第二次开始的时间间隔为3s.
5、源码下载
https://download.csdn.net/download/tangshiyilang/88627612
相关文章:

@Scheduled任务调度/定时任务-非分布式
1、功能概述 任务调度就是在规定的时间内执行的任务或者按照固定的频率执行的任务。是非常常见的功能之一。常见的有JDK原生的Timer, ScheduledThreadPoolExecutor以及springboot提供的Schduled。分布式调度框架如QuartZ、Elasticjob、XXL-JOB、SchedulerX、PowerJob等。 本文…...

【ARM Trace32(劳特巴赫) 使用介绍 14 -- Go.direct 介绍】
请阅读【Trace32 ARM 专栏导读】 文章目录 Trace32 Go.directGo配合程序断点使用Go 配合读写断点使用Go 快速回到上一层函数 System.Mode Go Trace32 Go.direct TRACE32调试过程中,会经常对芯片/内核进行控制,比如全速运行、暂停、单步等等。这篇文章先…...
第二十章 : Spring Boot 集成RabbitMQ(四)
第二十章 : Spring Boot 集成RabbitMQ(四) 前言 本章知识点:死信队列的定义、场景、作用以及原理、TTL方法的使用以及演示代码示例。 Springboot 版本 2.3.2.RELEASE ,RabbitMQ 3.9.11,Erlang 24.2死信队列 定义:什么是死信队列? 在RabbitMQ中,并没有提供真正意义…...

防止反编译,保护你的SpringBoot项目
ClassFinal-maven-plugin插件是一个用于加密Java字节码的工具,它能够保护你的Spring Boot项目中的源代码和配置文件不被非法获取或篡改。下面是如何使用这个插件来加密test.jar包的详细步骤: 安装并设置Maven: 首先确保你已经在你的开发环境中…...

OpenCV开发:MacOS源码编译opencv,生成支持java、python、c++各版本依赖库
OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习软件库。它为开发者提供了丰富的工具和函数,用于处理图像和视频数据,以及执行各种计算机视觉任务。 以下是 OpenCV 的一些主要特点和功能ÿ…...
【数据库设计和SQL基础语法】--查询数据--分组查询
一、分组查询概述 1.1 什么是分组查询 分组查询是一种 SQL 查询技术,通过使用 GROUP BY 子句,将具有相同值的数据行分组在一起,然后对每个组应用聚合函数(如 COUNT、SUM、AVG等)。这允许在数据集中执行汇总和统计操作…...

使用对象处理流ObjectOutputStream读写文件
注意事项: 1.创建的对象必须实现序列化接口,如果属性也是类,那么对应的类也要序列化 2.读写文件路径问题 3.演示一个例子 (1)操作的实体类FileModel,实体类中有Map,HashMap这些自带的本身就实现了序列化。 public class File…...

【高级网络程序设计】Block1总结
这一个Block分为四个部分,第一部分是Introduction to Threads and Concurrency ,第二部分是Interruptting and Terminating a Thread,第三部分是Keep Threads safety:the volatile variable and locks,第四部分是Beyon…...

linux下查看进程资源ulimit
ulimit介绍与使用 ulimit命令用于查看和修改进程的资源限制。下面是ulimit命令的使用方法: 查看当前资源限制: ulimit -a 这将显示当前进程的所有资源限制,包括软限制和硬限制。查看或设置单个资源限制: ulimit -<option> …...
C++ I/O操作---输入输出
本文主要介绍C I/O操作中的输入输出流。 目录 1 输入输出 2 输入输出流分类 3 C中的输入输出流 4 iostream 5 std::ofstream 6 std::fstream 7 std::getline 1 输入输出 C的输入输出是数据在不同设备之间的传输,即在硬盘、内存和外设之间的传输。 数据如水流…...

会 C# 应该怎么学习 C++?
会 C# 应该怎么学习 C? 在开始前我有一些资料,是我根据自己从业十年经验,熬夜搞了几个通宵,精心整理了一份「C的资料从专业入门到高级教程工具包」,点个关注,全部无偿共享给大家!!&a…...

CentOS 7 部署frp穿透内网
本文将介绍如何在CentOS 7.9上部署frp,并通过示例展示如何配置和测试内网穿透。 文章目录 (1)引言(2)准备工作(4)frps服务器端配置(5)frpc客户端配置(6&#…...
高效网络爬虫:代理IP的应用与实践
💂 个人网站:【 海拥】【神级代码资源网站】【办公神器】🤟 基于Web端打造的:👉轻量化工具创作平台🤟 代理 IP 推荐:👉品易 HTTP 代理 IP 💅 想寻找共同学习交流的小伙伴,…...

java设计模式-工厂方法模式
1.工厂方法(FactoryMethod)模式的定义 定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。这满足创建型模式中所要求的“创建与使用相分离”的特点。 2.工厂方法模式的主要优缺点 优点: 用户只需要知道具体工厂的名称…...

Python实验项目9 :网络爬虫与自动化
实验 1:爬取网页中的数据。 要求:使用 urllib 库和 requests 库分别爬取 http://www.sohu.com 首页的前 360 个字节的数据。 # 要求:使用 urllib 库和 requests 库分别爬取 http://www.sohu.com 首页的前 360 个字节的数据。 import urllib.r…...
实验三:指令调度和延迟分支
一、实验目的 加深对指令调度技术的理解。加深对延迟分支技术的理解。熟练掌握用指令调度技术来解决流水线中的数据冲突的方法。进一步理解指令调度技术对CPU性能的改进。进一步理解延迟分支技术对CPU性能的改进。 二、实验内容和步骤 首先要掌握MIPSsim模拟器的使用方法。见…...
【Oracle】PL/SQL语法、存储过程,触发器
一、Oracle数据类型 Orcle数据类型说明类比MySQL数据类型字符型CHAR固定长度的字符类型CHAR字符型VARCHAR2可变长度的字符类型VARCHAR字符型LONG大文本类型,最大2G数值型NUMBER数值类型,整数小数都可以,number(5)表示长度5的整数,…...

2020年第九届数学建模国际赛小美赛C题亚马逊野火解题全过程文档及程序
2020年第九届数学建模国际赛小美赛 C题 亚马逊野火 原题再现: 野火是指发生在乡村或荒野地区的可燃植被中的任何不受控制的火灾。这样的环境过程对人类生活有着重大的影响。因此,对这一现象进行建模,特别是对其空间发生和扩展进行建模&…...

保姆级 Keras 实现 YOLO v3 三
保姆级 Keras 实现 YOLO v3 三 一. 分配 anchor box二. 正负样本匹配规则三. 为每一个 anchor box 打标签3.1 anchor box 长什么样?3.2 每一个 anchor box 标签需要填充的信息有哪些?3.3 ( Δ x , Δ y , Δ w , Δ h ) (\Delta x, \Delta y, \Delta w, \Delta h) (Δx,Δy,…...

HPM6750系列--第十篇 时钟系统
一、目的 上一篇中《HPM6750系列--第九篇 GPIO详解(基本操作)》我们讲解了HPM6750 GPIO相关内容,再进一步讲解其他外设功能之前,我们有必要先讲解一下时钟系统。 时钟可以说是微控制器系统中的心脏,外设必须依赖时钟才…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...

EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...

前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
探索Selenium:自动化测试的神奇钥匙
目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程
STM32F1 本教程使用零知标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态解算,并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化,适合嵌入式及物联网开发者。在基础驱动上新增…...
API网关Kong的鉴权与限流:高并发场景下的核心实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中,API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关,Kong凭借其插件化架构…...