当前位置: 首页 > news >正文

Java 定时任务

为什么需要定时任务

定时任务(Scheduled Task)在开发中非常常用,它的核心作用就是 按照预定时间或间隔自动执行某些操作,无需人工干预。具体作用可以从以下几个方面理解

自动化执行重复任务

它可以避免人工手动触发操作,提高效率。

例如

  • 每天凌晨清理过期数据

  • 定时生成报表

  • 定时发送通知或邮件

系统维护与监控

它可以定期检查系统状态、日志、数据库健康情况等。

例如

  • 每隔5分钟监控服务器CPU、内存使用情况

  • 每天备份数据库或文件

  • 定期刷新缓存或重新加载配置

异步处理与任务调度

它结合异步线程池,可以 并发执行任务,提高系统吞吐量。

例如

  • 高频数据采集(IoT设备、传感器)

  • 批量消息处理或推送通知

实现延时或周期性逻辑

定时任务可以实现固定间隔、固定时间点、Cron表达式等灵活调度。

例如

  • 每隔5秒执行一次任务 → fixedRate / fixedDelay

  • 每天凌晨1点执行任务 → Cron表达式

下面,我们来讲一下如何在 spring 中继承定时任务

Java 配置

@Configuration
@EnableScheduling // 开启定时任务
public class TaskConfig {
​@Scheduled(fixedRate = 1000) // 定义一个定时任务public void scheduledTask() {System.out.println("我永远喜欢雪之下雪乃");}
}

@EnableScheduling 的作用是开启定时任务

@Scheduled 注解的作用是将被标注的方法注册为定时任务

来看一下该注解定义的一些参数

fixedRate 固定速率,每隔一段时间执行一次

它的开始时间是以上一次任务的开始执行的时间为基准的,隔 x 秒再触发下一次执行

如果上一次任务还没有完成,那么在此期间可以开始新任务吗

默认情况下,spring 的 @Scheduled 使用的是单线程调度器 ThreadPoolTaskScheduler,默认只有 1 个线程,所以即使在上一个线程还没执行完的期间,新线程也不会执行

如果要实现同一个任务 并行执行,就要实现多线程任务调度器,需要自己配置

@Configuration
@EnableScheduling
public class TaskConfig {@Beanpublic ThreadPoolTaskScheduler taskScheduler() {ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();scheduler.setPoolSize(5); // 开 5 个线程scheduler.setThreadNamePrefix("my-task-");return scheduler;}@Scheduled(fixedRate = 1000) // 定义一个定时任务public void scheduledTask() {System.out.println("我永远喜欢雪之下雪乃");}
}

这样,只要任务线程池中有还有空闲线程的情况下就,可以实现同一个任务并发执行

fixedDelay 固定延迟,任务执行完成后,延迟一定时间在执行

cron 配置 cron 表达式,可以精确控制时间

cron 表达式有 6~7 个字段

秒  分  时  日  月  周  [年]

字段含义

字段取值范围可以使用的特殊符号
0-59, - * /
0-59, - * /
0-23, - * /
1-31, - * ? L W
1-12 或 JAN-DEC, - * /
0-6(0=周日)或 SUN-SAT, - * ? L #
可选,1970-2099, - * /
* → 任意值
​
, → 多个值
​
- → 范围
​
/ → 步长(如 0/5 表示每 5 单位一次)
​
? → 日和周字段里的“占位符”,避免冲突
​
L → 最后(如月的最后一天,周的最后一天=周六)
​
W → 工作日(如 15W 表示离 15 号最近的工作日)
​
# → 第几个星期几(如 2#1 表示每月第一个星期一)

常见表达式

表达式含义
0 0/5 * * * ?每 5 分钟执行一次
0 0 2 * * ?每天凌晨 2 点执行
0 0 9,18 * * ?每天上午 9 点、下午 6 点各执行一次
0 0/10 9-17 * * ?每天 9 点到 17 点之间,每隔 10 分钟执行一次
0 30 10 ? * MON-FRI周一到周五,每天 10:30 执行
0 0 0 L * ?每月最后一天的 0 点执行
0 0 0 1 1 ?每年 1 月 1 日 0 点执行
0 15 10 ? * 6L每月最后一个周五的 10:15 执行

实现 SchedulingConfigurer 接口可以进行更复杂的定制

@Configuration
@EnableScheduling
public class TaskConfig implements SchedulingConfigurer {
​@Overridepublic void configureTasks(ScheduledTaskRegistrar registrar) {registrar.setScheduler(taskScheduler()); // 使用自定义线程池}
​@Beanpublic ThreadPoolTaskScheduler taskScheduler() {ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();scheduler.setPoolSize(10);  // 并发线程数scheduler.setThreadNamePrefix("my-scheduler-");scheduler.setWaitForTasksToCompleteOnShutdown(true);scheduler.setAwaitTerminationSeconds(30);return scheduler;}
}

注册任务

registrar.addCronTask(() -> System.out.println("Task1"), "0/5 * * * * ?"); // 注册静态任务
registrar.addTriggerTask(() -> System.out.println("Dynamic Task"),triggerContext -> {String cron = getCronFromDb(); // 比如从数据库/配置中心获取return new CronTrigger(cron).nextExecutionTime(triggerContext);}
); // 注册动态任务
registrar.addFixedRateTask(() -> System.out.println("FixedRate Task"), 5000); // 设置固定速率的定时任务
registrar.addFixedDelayTask(() -> System.out.println("FixedDelay Task"), 3000); // 设置固定间隔的定时任务

Spring 执行异步任务

上面我们了解到,如果只是使用框架默认提供的线程调度器,那么定时只能串行执行。这在一些场景下可能会影响效率。这时我们可以自定一个线程池,框架检测到 IoC 容器中存在其他线程池就不会使用单线程调度器,转而使用我们自己配置的多线程池。

除了这种方法,我们还可以使用异步线程

看配置

@Configuration
@EnableAsync
public class AsyncConfig {
​@Bean("taskExecutor")public Executor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(4);executor.setMaxPoolSize(8);executor.setQueueCapacity(1000);executor.setThreadNamePrefix("Async-");executor.initialize();return executor;}
}

这是一段异步任务配置类,主要作用是定义一个自定义的线程池,用来执行 @Async 注解标注的异步方法

@EnableAsync 注解,启用 spring 的异步方法执行能力

@Async("taskExecutor")
public void asyncTask() {// 这里的代码会异步执行,不会阻塞主线程
}

@Async 标注一个异步方法,它会使用自定的线程池异步执行

异步执行适合 IO密集型后台批量任务

比如:异步写入 Redis、发送邮件、处理消息队列等

我们上面写的定时任务就可以使用该注解,使其变为一个可以并行的异步任务

@Scheduled(fixedRate = 1000) // 定义一个定时任务
@Async
public void scheduledTask() {System.out.println("我永远喜欢雪之下雪乃");
}

当然,还有其他定时任务框架,如 Quartz,这里没用到,用到再说

http://www.dtcms.com/a/462360.html

相关文章:

  • 如何创建网站的二维码如何编辑 wordpress 主题
  • C++内存模型深度剖析从并发编程到原子操作的内存序语义
  • seo优化方法有哪些
  • 土动三轴试验机技术指标
  • 漳州正规网站建设公司wordpress google插件
  • 营销网站首页设计wordpress 博客主题
  • 鸿蒙路上的那些事:从初学者到资源创作者
  • 河北网站开发联系电话4a网站建设公司
  • 在 VS Code 中让整个工作区只读
  • 优秀网站菜单wordpress注册收不到邮件
  • 合肥网站建设pqiw目录网站做外链
  • 泉州自主建站模板网站设计费用价目表
  • 让水分子“导航”,突破蛋白–糖类分子对接难题
  • 在dify工作流中如何定义filename自动生成
  • asp 网站后台免费的企业网页制作网站
  • ILSpy下载和安装教程(附安装包,图文并茂)
  • 微信小程序-9-上滑加载更多和下拉刷新及小程序更新分享和转发
  • 【AES加密专题】1.AES的原理详解和加密过程
  • hello_servlet
  • 易拉罐和瓶子分类数据集 6059张图片,支持yolo,coco json,paschal voc xml格式,识别率可达92.5%,文末提供下载地址
  • 1 玩转Linux命令行:基础文件操作实战教程
  • 图观 流渲染打包服务器
  • 为什么只有中国做网站需要备案建站技术博客
  • 最好的微网站建设价格搜索引擎排名国内
  • 自动化测试中元素定位失败的解决策略
  • 心痛之窗:滑动窗口算法解爱与愁的心痛(洛谷P1614)
  • 鸿蒙HTTP请求老是发不出去?一文带你彻底排查所有坑!
  • c# 开发网站开发做市级网站需要什么
  • 购物网站建设的必要性电商设计年终总结
  • 元宵节html+css+js 5页