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

Java的各类定时任务实现

在 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.zskr.cn/news/18827.html

相关文章:

  • 03:运算符
  • python静态类型之any
  • 2025 年最新金蝶云服务商推荐榜单:聚焦铂金伙伴技术实力与万级客户口碑,助力企业数字化转型精准选型上海金蝶云服务商推荐
  • 使用 C++ 和 minizip 实现 ZIP 压缩解压工具
  • 西部数码使用外部dns服务器怎么配置解析
  • 一看就懂,Oracle认证体系中的OCP中级认证
  • 2025 年试验机生产厂家最新推荐榜单:聚焦优质企业,助力精准选购高低温等各类试验设备弹簧拉压/弹簧疲劳/高频弹簧疲劳/U型弹簧专用试验机厂家推荐
  • IIS/如何查看IIS上部署网站的实时连接数
  • 拼叨叨砍价系统:实体店低成本引流的营销利器
  • SLS Copilot 实践:基于 SLS 灵活构建 LLM 应用的数据基础设施
  • 超高密度2kW GaN基低压电机驱动器的设计 - 实践
  • 在AI技术唾手可得的时代,挖掘新需求成为核心竞争力——某知名AI代理框架需求洞察
  • 02:基础数据类型
  • 接口测试全流程实战:从工具到架构的深度解析
  • C# Send and receive big file via stream
  • 2、python get请求
  • 可解释AI技术解析与模型监控实践
  • 开源多场景问答社区论坛Apache Answer本地部署并发布至公网使用 - 实践
  • 2025异型钢厂家最新推荐榜:定制化生产与卓越品质引领者
  • 2025热喷铝厂家最新推荐榜:品质卓越与专业服务的行业首选!
  • 2025方钢厂家,异型钢厂家,六角钢厂家最新推荐榜:品质与性价比兼备的首选品牌!
  • QuickLook软件!一款鼠标单击PDF即能显示内容的软件!
  • iOS 26 崩溃日志深度指南,如何收集、符号化、定位与监控 - 实践
  • 2020CSP-J2比赛记录题解
  • 让博客园设置支持PlantUml画图
  • 光谱相机的未来趋势 - 详解
  • Hall定理学习笔记
  • 面向对象抽象,接口多态综合-动物模拟系统
  • 个人微信开发文档
  • 象棋图片转FEN字符串详细教程