当前位置: 首页 > 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.hskmm.com/?act=detail&tid=28664

相关文章:

  • 03:运算符
  • JavaScript内存泄露原因及解决方案
  • 数据类型扩展
  • 2025 年最新金蝶云服务商推荐榜单:聚焦铂金伙伴技术实力与万级客户口碑,助力企业数字化转型精准选型上海金蝶云服务商推荐
  • OIFHA251011 比赛总结
  • P2051 [AHOI2009] 中国象棋 个人题解
  • 一种智能调度分布式路径计算解决方案
  • 使用 C++ 和 minizip 实现 ZIP 压缩解压工具
  • 一看就懂,Oracle认证体系中的OCP中级认证
  • 2025 年试验机生产厂家最新推荐榜单:聚焦优质企业,助力精准选购高低温等各类试验设备弹簧拉压/弹簧疲劳/高频弹簧疲劳/U型弹簧专用试验机厂家推荐
  • IIS/如何查看IIS上部署网站的实时连接数
  • 拼叨叨砍价系统:实体店低成本引流的营销利器
  • 2025 自动门生产厂家最新推荐榜:权威筛选优质品牌,含选购指南与实力厂家深度解析
  • 医德出诊排班挂号管理系统:医院高效运营与便民服务的智能解决方案
  • 一佳教育培训课程系统小程序:一站式教育数字化解决方案
  • Supabase:无需后端代码的 Web 开发完整解决方案
  • Halo RAG!
  • SLS Copilot 实践:基于 SLS 灵活构建 LLM 应用的数据基础设施
  • 2025 木饰面源头厂家最新推荐榜单:21 年标杆企业领衔,背景墙/全屋 /格栅/碳晶板全品类最新推荐及选购指南
  • 2025 年北京市管道疏通公司最新推荐排行榜:覆盖多城区、高压技术赋能的优质企业优选榜单西城区/朝阳区/丰台区/石景山/海淀区管道疏通公司推荐
  • 2025 年北京市清理化粪池公司最新推荐排行榜:聚焦高压技术与全城服务的权威甄选朝阳区/丰台区/海淀区/通州区清理化粪池厂家推荐
  • 报表方案Stimulsoft 2025.4 重磅发布!新增AI报表助手、C#脚本支持、全新图表类型等多项功能!
  • Prometheus的Exporter的数据采集机制
  • 2025 年珠三角 / 中山 / 东莞 / 佛山厂房出售公司推荐:中创集团产业生态型厂房的价值与服务解析
  • CTFshow-web方向(更新中)
  • 拷贝和上传文件,涉及隐私协议
  • 2025储罐厂家,钢衬塑储罐,钢塑复合储罐,化工储罐,防腐储罐,PE储罐,盐酸储罐,硫酸储罐,聚丙烯储罐,不锈钢储罐,次氯酸钠储罐各类型最新推荐榜:品质卓越与技术创新的行业先锋!
  • 2025 年国内标志牌生产厂家最新推荐排行榜:聚焦优质企业助力客户精准选择道路/限速/公路/施工/警示/限高/三角/安全标志牌厂家推荐
  • 在Scala中,如何在泛型类中使用类型参数?
  • Maple 2025 来了!AI 赋能 + 6000 + 命令,破解数学计算、科研与教学痛点