Java定时器如何实现
- 后端开发
- 2025-07-01
- 4
基础方案:java.util.Timer (单线程)
适用场景:简单单线程任务(如间隔日志备份)
import java.util.Timer; import java.util.TimerTask; public class BasicTimerExample { public static void main(String[] args) { Timer timer = new Timer(); TimerTask task = new TimerTask() { @Override public void run() { System.out.println("任务执行: " + new java.util.Date()); } }; // 延迟1秒启动,每2秒执行一次 timer.schedule(task, 1000, 2000); // 10秒后终止定时器 try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } timer.cancel(); // 释放资源 } }
注意事项:
- 单线程设计:一个任务阻塞会导致后续任务延迟
- 异常影响:任务抛出未处理异常会终止整个定时器
- 替代方案:Java 5+推荐用ScheduledExecutorService替代
推荐方案:ScheduledExecutorService (线程池)
适用场景:多任务并发、需资源控制(如订单状态轮询)
优势:
- 线程池管理:避免单点故障
- 支持Callable:可获取任务返回值
- 灵活调度:提供scheduleWithFixedDelay(任务结束到下次开始间隔)和scheduleAtFixedRate(固定频率)
Spring Boot集成方案:@Scheduled注解
适用场景:Spring项目快速集成(如定时数据同步)
-
启用定时配置(在启动类添加):

-
创建定时任务类:
@Component public class SpringScheduler { // 每5分钟执行(cron表达式) @Scheduled(cron = "0 */5 * * * ?") public void cronJob() { System.out.println("CRON任务: " + LocalDateTime.now()); } // 固定速率(上次开始后3秒) @Scheduled(fixedRate = 3000) public void fixedRateJob() { System.out.println("固定速率任务"); } // 带初始延迟(启动后2秒开始,每次间隔4秒) @Scheduled(initialDelay = 2000, fixedDelay = 4000) public void delayedJob() { System.out.println("延迟启动任务"); } }配置参数(application.properties):
# 自定义线程池大小(默认单线程) spring.task.scheduling.pool.size=5 -
添加依赖(Maven):
-
创建调度任务:
public class QuartzJob implements Job { @Override public void execute(JobExecutionContext context) { System.out.println("Quartz任务触发: " + new Date()); } }
- 资源泄露预防:
- 所有调度器必须显式关闭(shutdown())
- Spring项目中利用@PreDestroy注解
- 时间精度:
- 系统时钟跳变可能影响调度(考虑HashedWheelTimer)
高级方案:Quartz框架
适用场景:分布式调度、持久化存储(如跨服务器定时报表)

public class QuartzScheduler {
public static void main(String[] args) throws SchedulerException {
// 1. 创建任务实例
JobDetail job = JobBuilder.newJob(QuartzJob.class)
.withIdentity(“reportJob”).build();
// 2. 配置触发器(每10秒) Trigger trigger = TriggerBuilder.newTrigger() .withSchedule(SimpleScheduleBuilder.simpleSchedule() .withIntervalInSeconds(10) .repeatForever()) .build(); // 3. 启动调度器 Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); scheduler.scheduleJob(job, trigger); scheduler.start(); // 4. 关闭(实际应用中通过钩子关闭) Thread.sleep(30000); scheduler.shutdown(); } **核心优势**: - 集群支持:故障转移与负载均衡 - 持久化:任务状态存储到数据库 - 日历调度:排除节假日等特殊日期 --- ### **关键注意事项** 1. **线程安全**: - `Timer`和单线程`@Scheduled`需避免同步代码块 - 多线程方案中优先使用`Concurrent`集合类 2. **异常处理**: ```java executor.scheduleAtFixedRate(() -> { try { // 业务代码 } catch (Exception e) { logger.error("任务异常", e); } }, 0, 1, TimeUnit.SECONDS);
方案选型建议
| 场景 | 推荐方案 |
|---|---|
| 简单单机任务 | ScheduledExecutorService |
| Spring Boot项目 | @Scheduled注解 |
| 分布式/持久化需求 | Quartz框架 |
| 旧版Java兼容 | Timer(谨慎使用) |
引用说明:本文代码示例基于Oracle官方Java 17 API文档、Spring Framework 5.3文档及Quartz Scheduler 2.3官方指南编写,关键实践参考《Java并发编程实战》(Brian Goetz著)中线程池管理原则。
