Java的各类定时任务实现

news/2025/10/11 15:04:38/文章来源:https://www.cnblogs.com/dirgo/p/19135070

在 Java 中实现定时任务有多种方式,下面详细介绍各种方法的使用:

1. Timer 和 TimerTask(基础版)

import java.util.Timer;
import java.util.TimerTask;public class TimerExample {public static void main(String[] args) {Timer timer = new Timer();// 创建定时任务TimerTask task = new TimerTask() {@Overridepublic void run() {System.out.println("定时任务执行了,时间: " + new Date());}};// 安排任务执行// 延迟1秒后执行,然后每5秒执行一次timer.schedule(task, 1000, 5000);// 在特定时间执行// Calendar calendar = Calendar.getInstance();// calendar.add(Calendar.SECOND, 10);// timer.schedule(task, calendar.getTime());// 10秒后停止定时器try {Thread.sleep(10000);} catch (InterruptedException e) {e.printStackTrace();}timer.cancel();}
}

2. ScheduledExecutorService(推荐)

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;public class ScheduledExecutorExample {public static void main(String[] args) {// 创建调度线程池ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);// 任务1:固定延迟执行Runnable task1 = () -> {System.out.println("任务1执行 - " + Thread.currentThread().getName() + " - " + new Date());};// 任务2:带返回值的任务ScheduledFuture<String> task2 = scheduler.schedule(() -> {System.out.println("一次性任务执行");return "任务完成";}, 3, TimeUnit.SECONDS);// 安排任务执行// 延迟2秒后开始执行,然后每5秒执行一次(固定延迟)ScheduledFuture<?> scheduledTask = scheduler.scheduleWithFixedDelay(task1, 2, 5, TimeUnit.SECONDS);// 固定频率执行(不考虑任务执行时间)// scheduler.scheduleAtFixedRate(task1, 2, 5, TimeUnit.SECONDS);try {// 运行20秒Thread.sleep(20000);// 取消任务scheduledTask.cancel(false);// 获取一次性任务的结果if (task2.isDone()) {System.out.println("一次性任务结果: " + task2.get());}} catch (Exception e) {e.printStackTrace();} finally {// 关闭调度器scheduler.shutdown();try {if (!scheduler.awaitTermination(5, TimeUnit.SECONDS)) {scheduler.shutdownNow();}} catch (InterruptedException e) {scheduler.shutdownNow();}}}
}

3. Spring Framework 的 @Scheduled(最常用)

配置类或者主启动类上添加 @EnableScheduling注解

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;@Configuration
@EnableScheduling
public class SpringSchedulerConfig {// 启用定时任务支持
}

定时任务类添加@Component

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;@Component
public class SpringScheduledTasks {/*** 固定速率执行 - 每5秒执行一次* 从上一次开始时间计算*/@Scheduled(fixedRate = 5000)public void fixedRateTask() {System.out.println("固定速率任务 - " + LocalDateTime.now());}/*** 固定延迟执行 - 上一次执行完成后延迟3秒再执行*/@Scheduled(fixedDelay = 3000)public void fixedDelayTask() {try {// 模拟任务执行时间TimeUnit.SECONDS.sleep(1);System.out.println("固定延迟任务 - " + LocalDateTime.now());} catch (InterruptedException e) {Thread.currentThread().interrupt();}}/*** 初始延迟 - 应用启动后延迟10秒开始执行,然后每30秒执行一次*/@Scheduled(initialDelay = 10000, fixedRate = 30000)public void initialDelayTask() {System.out.println("初始延迟任务 - " + LocalDateTime.now());}/*** Cron 表达式 - 更灵活的时间控制*/@Scheduled(cron = "0 */2 * * * ?") // 每2分钟执行一次public void cronTask() {System.out.println("Cron任务执行 - " + LocalDateTime.now());}/*** Cron 表达式示例*/@Scheduled(cron = "0 0 12 * * ?") // 每天中午12点执行public void noonTask() {System.out.println("中午任务执行 - " + LocalDateTime.now());}/*** 支持占位符,从配置文件中读取*/@Scheduled(cron = "${task.cron.expression:0 */5 * * * ?}")public void configurableTask() {System.out.println("可配置任务 - " + LocalDateTime.now());}
}

4. Quartz Scheduler(企业级)

添加依赖(Maven)

<dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.3.2</version>
</dependency>

Quartz 配置

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;public class QuartzExample {// 定义任务public static class SimpleJob implements Job {@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {System.out.println("Quartz任务执行 - " + new Date());// 获取传递的参数JobDataMap dataMap = context.getJobDetail().getJobDataMap();String message = dataMap.getString("message");if (message != null) {System.out.println("消息: " + message);}}}public static void main(String[] args) throws SchedulerException {// 创建调度器Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();// 定义任务详情JobDetail job = JobBuilder.newJob(SimpleJob.class).withIdentity("simpleJob", "group1").usingJobData("message", "Hello Quartz!").build();// 定义触发器Trigger trigger = TriggerBuilder.newTrigger().withIdentity("simpleTrigger", "group1").startNow().withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(10).repeatForever()).build();// 安排任务scheduler.scheduleJob(job, trigger);// 启动调度器scheduler.start();// 运行一段时间后关闭try {Thread.sleep(60000);} catch (InterruptedException e) {e.printStackTrace();}scheduler.shutdown();}
}

5. 基于 Spring + Quartz 的集成

配置类

import org.quartz.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class QuartzConfig {@Beanpublic JobDetail sampleJobDetail() {return JobBuilder.newJob(SampleQuartzJob.class).withIdentity("sampleJob").storeDurably().build();}@Beanpublic Trigger sampleJobTrigger() {SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(30).repeatForever();return TriggerBuilder.newTrigger().forJob(sampleJobDetail()).withIdentity("sampleTrigger").withSchedule(scheduleBuilder).build();}
}

任务类

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;public class SampleQuartzJob extends QuartzJobBean {@Overrideprotected void executeInternal(JobExecutionContext context) throws JobExecutionException {System.out.println("Spring Quartz 任务执行 - " + new Date());}
}

6. Cron 表达式详解

/*** Cron 表达式格式: [秒] [分] [时] [日] [月] [周] [年] (年可选)* * 常用示例:* "0 0 12 * * ?"          每天12点* "0 15 10 ? * *"         每天10:15* "0 0/5 14,18 * * ?"     每天14点和18点,每5分钟一次* "0 0-5 14 * * ?"        每天14:00到14:05每分钟执行* "0 0/30 9-17 * * ?"     朝九晚五工作时间内每半小时* "0 0 12 ? * WED"        每周三中午12点* "0 15 10 15 * ?"        每月15日上午10:15*/

7. 最佳实践和注意事项

异常处理

@Component
public class SafeScheduledTask {@Scheduled(fixedRate = 5000)public void safeTask() {try {// 业务逻辑performBusinessLogic();} catch (Exception e) {// 记录日志,但不抛出异常,避免任务停止System.err.println("定时任务执行失败: " + e.getMessage());// 可以添加告警逻辑}}private void performBusinessLogic() {// 模拟业务逻辑if (Math.random() < 0.1) {throw new RuntimeException("模拟异常");}System.out.println("业务逻辑执行成功");}
}

分布式环境考虑

@Component
public class DistributedScheduledTask {@Autowiredprivate DistributedLockService lockService;@Scheduled(cron = "0 */5 * * * ?")public void distributedTask() {String lockKey = "distributed_task_lock";if (lockService.tryLock(lockKey, 300)) { // 锁定5分钟try {// 执行任务System.out.println("获取分布式锁,执行任务");// 业务逻辑...} finally {lockService.unlock(lockKey);}} else {System.out.println("未获取到锁,跳过执行");}}
}

总结对比

方式 优点 缺点 适用场景
Timer 简单易用 单线程,任务阻塞 简单的单机任务
ScheduledExecutorService 线程池管理,更灵活 配置相对复杂 需要精细控制的定时任务
Spring @Scheduled 配置简单,集成方便 功能相对基础 Spring项目中的常规定时任务
Quartz 功能强大,支持集群 配置复杂,依赖多 企业级复杂调度需求
Spring + Quartz 结合两者优势 配置较复杂 需要Quartz功能的Spring项目

推荐使用顺序:Spring @Scheduled → ScheduledExecutorService → Quartz,根据项目复杂度选择合适的方案。

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

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

相关文章

03:运算符

> 一篇搞定C语言所有运算符:算术、关系、逻辑、位、赋值、三目、sizeof、优先级表全收录,附短路代码实验,写表达式不再懵!一、算术运算符(整型&浮点通用)运算符 功能 示例 备注+ 加/单目正 a + b、+a 单目…

JavaScript内存泄露原因及解决方案

在 JavaScript 中,内存泄漏通常发生在不需要的内存没有被垃圾回收器释放时。以下是常见的几种情况: 1. 意外的全局变量 // 意外的全局变量 function foo() {bar = "这是一个全局变量"; // 没有使用 var/le…

数据类型扩展

整数扩展 整数按进制可以分为二进制0b(binary)开头,八进制0开头,十进制和十六进制0x开头; 因此,二进制的10输出为2,因为逢2进1,同样地,0x10代表16,因为在十六进制中,逢十六进1;同时,在十六进制中,10-15表…

python静态类型之any

python静态类型之any 漫思

2025 年最新金蝶云服务商推荐榜单:聚焦铂金伙伴技术实力与万级客户口碑,助力企业数字化转型精准选型上海金蝶云服务商推荐

当前数字经济浪潮下,企业数字化转型进程不断加快,ERP 系统作为转型核心支撑,其服务商的选择直接决定转型成效。但金蝶云服务商市场资质杂乱、服务能力悬殊,众多企业在选型时屡屡碰壁,不仅难以辨别服务商真实水平,…

OIFHA251011 比赛总结

比赛:OIFHA251011 日期:\(25.10.11\),场地:\(\text{OIFHA}\),排名:\(6/16\) 估分:\(100+100+0+20=220\) 终分:\(100+100+10+20=220\) 应该得分:\(100+100+10+40=250\) 失分 没想到 \(T_4\) 可以直接离线下来慢…

P2051 [AHOI2009] 中国象棋 个人题解

题目链接 题目描述: 给你一个 \(n*m\) 的棋盘,棋盘的每行和每列只能放置有 \(2\) 个棋子(可以放置 \(0\) 个棋子),问有多少种放置方案 解题方法: 这道题看起来像是八皇后问题的加强版,但是如果一个个枚举的话,…

一种智能调度分布式路径计算解决方案

本文分享自天翼云开发者社区《一种智能调度分布式路径计算解决方案》.作者:蒋辉 背景技术 传统的CDN动态加载智能路由系统对用户动态请求,主要通过探测服务器主动发起周期性的探测请求,探测CDN中转节点和源站的可用…

使用 C++ 和 minizip 实现 ZIP 压缩解压工具

在软件开发中,文件压缩和解压是常见的需求。今天我们来介绍一个基于 minizip 库的 C++ ZIP 工具类 - ZipUtility,它可以轻松地处理 ZIP 文件的创建和解压。这篇文章使用AI辅助编写。核心功能 1. 压缩功能 ZipUtility…

西部数码使用外部dns服务器怎么配置解析

西部数码使用外部dns服务器怎么配置解析在西部数码购买的域名如果使用的dns是外部的,要在该外部dns管理平台去设置解析 比如使用的阿里云的dns如何设置解析 在阿里云dns管理页面找到dns粘贴到西部数码该域名的解析地址…

一看就懂,Oracle认证体系中的OCP中级认证

对于刚接触Oracle数据库或者打算往数据库领域发展的人来说,需要了解一下这个认证:Oracle的中级认证OCP认证专家。 OCP认证全称为Oracle Certified Professional(甲骨文认证专家),是全球知名的IT技术认证体系之一,由…

实用指南:SDN 控制器深度剖析:架构、对比与实践部署

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2025 年试验机生产厂家最新推荐榜单:聚焦优质企业,助力精准选购高低温等各类试验设备弹簧拉压/弹簧疲劳/高频弹簧疲劳/U型弹簧专用试验机厂家推荐

在工业生产与科研检测的关键环节,试验机对保障产品质量、验证材料性能起着不可替代的作用。随着市场需求激增,试验机生产厂家数量骤增,但行业乱象也随之显现,产品质量参差不齐、技术水平差距悬殊、服务体系不完善等…

IIS/如何查看IIS上部署网站的实时连接数

我们在IIS发布的Web网站,如何查看网站实时的连接数呢? 1、首先打开运行框,输入perfmon.msc 2、打开监视工具-->性能监视器 3、点击 “+”号,添加计数项 Web Service/Current Connections 4、可以查看到网站的实…

Supabase:无需后端代码的 Web 开发完整解决方案

在现代 Web 应用开发中,构建 MVP(最简可行产品)时,后端基础设施的搭建常常成为主要瓶颈。开发者需要处理数据库、API、用户认证、权限控制、文件存储等多个模块,开发成本较高。 Supabase 提供了一种替代方案:它以…

Halo RAG!

Halo AI 助手插件最新版本深度集成了 RAG 问答功能,支持将 Halo 文章或 Docsme 文档作为知识库,为访客提供智能问答服务。用户需先创建知识库,配置嵌入模型并选择内容范围以建立索引;随后创建问答应用,关联知识库…

拼叨叨砍价系统:实体店低成本引流的营销利器

在互联网营销深入各行业的当下,“砍一刀” 凭借强社交裂变属性,已成为大众熟知的营销模式。拼叨叨砍价系统基于这一模式,针对实体店商家营销痛点,打造出轻量化、易操作的砍价活动模块,支持微信公众号部署,能帮助…

2025 自动门生产厂家最新推荐榜:权威筛选优质品牌,含选购指南与实力厂家深度解析

在出入口自动化浪潮下,自动门已成为商业综合体、医院、工业厂区等场景的刚需设备,但其市场呈现 “繁荣与乱象并存” 的态势。部分品牌缺乏核心技术,产品故障率高、寿命短,无形中增加使用成本;售后体系缺失导致故障…

grafana-使用grafana-image-renderer:v4.0.17渲染仪表盘图像

grafana-使用grafana-image-renderer:v4.0.17渲染仪表盘图像v4.0.17需要grafana版本在11.3.8以上。我的是centos7, 升级grafana很简单,备份一下数据和配置,然后停掉grafana服务,然后使用【rpm -Uvh 新版本的rpm包 …

医德出诊排班挂号管理系统:医院高效运营与便民服务的智能解决方案

在数字化医疗浪潮下,传统挂号模式的低效、信息不透明等问题日益凸显,患者就医体验不佳,医院管理压力也持续增加。医德出诊排班挂号系统作为一款聚焦医疗服务场景的数字化工具,依托微信公众号生态,整合出诊排班、预…