本文目录导读:

- 使用
java.util.Timer(基础、简单) - 使用
ScheduledExecutorService(推荐单机场景) - 使用 Spring 的
@Scheduled注解(企业级最常用) - 使用 Quartz 框架(复杂场景、分布式)
- 各方案对比总结
- 常见Cron表达式示例
Java中实现定时任务有多种方式,从简单到复杂、从单机到分布式,各有适用场景,以下是几种最常用的实现方案及具体案例:
使用 java.util.Timer(基础、简单)
这是JDK自带的定时器,适合简单的单机任务。
import java.util.Timer;
import java.util.TimerTask;
public class TimerDemo {
public static void main(String[] args) {
Timer timer = new Timer("MyTimer");
// 延迟1秒后执行,之后每3秒执行一次
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("任务执行时间: " + System.currentTimeMillis());
}
}, 1000, 3000);
// 程序运行10秒后停止
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
timer.cancel();
}
}
缺点:所有任务使用单线程,一个任务异常会影响其他任务;不支持Cron表达式。
使用 ScheduledExecutorService(推荐单机场景)
线程池实现的定时任务,性能更好,支持多线程并发。
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ScheduledExecutorDemo {
public static void main(String[] args) {
// 创建支持定时任务的线程池
ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);
// 任务1:固定速率执行(延迟1秒,每2秒执行一次)
executor.scheduleAtFixedRate(() -> {
System.out.println("任务1执行: " + Thread.currentThread().getName()
+ " - " + System.currentTimeMillis());
}, 1, 2, TimeUnit.SECONDS);
// 任务2:固定延迟执行(任务结束后固定延迟再执行)
executor.scheduleWithFixedDelay(() -> {
try {
Thread.sleep(1000); // 模拟任务耗时
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("任务2执行: " + Thread.currentThread().getName());
}, 1, 3, TimeUnit.SECONDS);
// 让程序运行一段时间
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
executor.shutdown();
}
}
特点:支持多线程、异常处理更灵活、可返回Future。
使用 Spring 的 @Scheduled 注解(企业级最常用)
在Spring Boot项目中,这是最常用、最优雅的方式。
1 添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
2 启动类启用定时任务
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling // 启用定时任务
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
3 编写定时任务
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
@Component
public class ScheduledTasks {
// 1. 固定延迟:任务结束后延迟2秒再执行
@Scheduled(fixedDelay = 2000)
public void taskWithFixedDelay() {
System.out.println("fixedDelay任务: " + LocalDateTime.now());
}
// 2. 固定速率:每3秒执行一次(不等待上一个任务完成)
@Scheduled(fixedRate = 3000)
public void taskWithFixedRate() {
System.out.println("fixedRate任务: " + LocalDateTime.now());
}
// 3. 使用Cron表达式:每天10:15执行
@Scheduled(cron = "0 15 10 * * ?")
public void taskWithCron() {
System.out.println("Cron任务: 每天10:15执行 - " + LocalDateTime.now());
}
// 4. 初始延迟:启动后5秒开始,之后每5秒执行
@Scheduled(initialDelay = 5000, fixedRate = 5000)
public void taskWithInitialDelay() {
System.out.println("延迟任务: " + LocalDateTime.now());
}
}
4 配置线程池(可选)
避免定时任务阻塞主线程,可自定义线程池:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
@Configuration
public class SchedulingConfig {
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(5);
taskScheduler.setThreadNamePrefix("task-");
return taskScheduler;
}
}
使用 Quartz 框架(复杂场景、分布式)
适合需要持久化、集群、动态管理等复杂场景。
1 添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
2 创建任务类
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
public class MyQuartzJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext context)
throws JobExecutionException {
System.out.println("Quartz任务执行: " + System.currentTimeMillis());
// 获取参数
String param = context.getJobDetail().getJobDataMap().getString("param");
System.out.println("参数: " + param);
}
}
3 配置定时器
import org.quartz.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class QuartzConfig {
@Bean
public JobDetail myJobDetail() {
// 定义任务,绑定JobData参数
JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put("param", "hello");
return JobBuilder.newJob(MyQuartzJob.class)
.withIdentity("myJob", "group1")
.usingJobData(jobDataMap)
.storeDurably()
.build();
}
@Bean
public Trigger myTrigger() {
// 定义触发器,Cron表达式:每5秒执行一次
CronScheduleBuilder scheduleBuilder =
CronScheduleBuilder.cronSchedule("0/5 * * * * ?");
return TriggerBuilder.newTrigger()
.forJob(myJobDetail())
.withIdentity("myTrigger", "group1")
.withSchedule(scheduleBuilder)
.build();
}
}
各方案对比总结
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| Timer | 简单、原生支持 | 单线程、异常影响大 | 极简单场景、JDK1.3+ |
| ScheduledExecutorService | 线程池、异常隔离 | 不支持Cron | 单机中等复杂度 |
| @Scheduled | 注解开发、Cron支持 | 默认单线程 | Spring Boot项目首选 |
| Quartz | 持久化、集群、动态管理 | 配置复杂、依赖重 | 企业级分布式场景 |
常见Cron表达式示例
0 0 12 * * ? - 每天中午12点
0 0/5 * * * ? - 每5分钟
0 0 8-18 * * ? - 每天8点到18点每小时执行
0 0 0 1 * ? - 每月1号零点
0 15 10 ? * 1-5 - 周一到周五10:15
0 0/30 9-17 * * ? - 9点到17点之间每30分钟
推荐选择:如果是Spring Boot项目,优先使用@Scheduled注解,简单高效;如果需要集群或持久化,再考虑Quartz。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播