本文目录导读:

- 基础方案:使用
java.util.Timer - 企业级方案:
ScheduledExecutorService(推荐) - Spring Boot集成 Quartz(最强大,支持Cron)
- Spring Boot @Scheduled 注解(简单实用,推荐)
- 分布式场景:Redis + Redisson的分布式调度
- 选择建议
在Java中实现定时任务有多种方式,从简单到复杂,根据你的需求场景选择合适的方法,以下是几种主流的实现方案:
基础方案:使用 java.util.Timer
适合简单的单次或固定周期任务,不需要复杂调度。
import java.util.Timer;
import java.util.TimerTask;
public class TimerExample {
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);
// 如果需要停止任务
// timer.cancel();
}
}
缺点:所有任务共用一个线程,一个任务异常会影响其他任务;不支持cron表达式。
企业级方案:ScheduledExecutorService(推荐)
从Java 5开始引入,基于线程池,性能更好,更稳定。
import java.util.concurrent.*;
public class ScheduledExecutorExample {
public static void main(String[] args) throws InterruptedException {
// 创建线程池,核心线程数2
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
// 一次性任务:延迟5秒执行
scheduler.schedule(() -> {
System.out.println("一次性任务执行:" + System.currentTimeMillis());
}, 5, TimeUnit.SECONDS);
// 固定延迟任务:上次执行完后延迟3秒再执行
scheduler.scheduleWithFixedDelay(() -> {
System.out.println("固定延迟任务:" + System.currentTimeMillis());
try {
Thread.sleep(2000); // 模拟任务执行耗时
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}, 0, 3, TimeUnit.SECONDS);
// 固定频率任务:每2秒执行一次,不受任务耗时影响
scheduler.scheduleAtFixedRate(() -> {
System.out.println("固定频率任务:" + System.currentTimeMillis());
}, 0, 2, TimeUnit.SECONDS);
// 让主线程运行一段时间再关闭
Thread.sleep(15000);
scheduler.shutdown();
}
}
优点:基于线程池,支持多任务并行;异常处理更灵活;适合生产环境。
Spring Boot集成 Quartz(最强大,支持Cron)
适合复杂的定时任务调度,如“每天上午10点执行”等。
添加依赖(pom.xml)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
创建任务类
import org.quartz.Job;
import org.quartz.JobExecutionContext;
public class MyQuartzJob implements Job {
@Override
public void execute(JobExecutionContext context) {
System.out.println("Quartz任务执行:" + System.currentTimeMillis());
// 业务逻辑代码
}
}
配置调度器
import org.quartz.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class QuartzConfig {
@Bean
public JobDetail myJobDetail() {
return JobBuilder.newJob(MyQuartzJob.class)
.withIdentity("myJob", "group1")
.storeDurably()
.build();
}
@Bean
public Trigger myTrigger() {
// Cron表达式:每天上午10:15执行
// 格式: 秒 分 时 日 月 周 [年]
String cronExpression = "0 15 10 * * ?";
return TriggerBuilder.newTrigger()
.forJob(myJobDetail())
.withIdentity("myTrigger", "group1")
.withSchedule(CronScheduleBuilder.cronSchedule(cronExpression))
.build();
}
}
本机测试用的Cron示例
// 每5秒执行一次 "*/5 * * * * ?" // 每天中午12点整执行 "0 0 12 * * ?" // 每周一至周五上午10:30执行 "0 30 10 ? * MON-FRI"
Spring Boot @Scheduled 注解(简单实用,推荐)
适合轻量级应用,Spring Boot原生支持,无需额外依赖。
启用定时任务
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);
}
}
定义定时任务
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class ScheduledTasks {
// 固定频率:每5秒执行一次(从任务开始计时)
@Scheduled(fixedRate = 5000)
public void reportCurrentTime() {
System.out.println("固定频率执行:" + System.currentTimeMillis());
}
// 固定延迟:上次执行完成后延迟3秒再执行
@Scheduled(fixedDelay = 3000)
public void processData() {
System.out.println("固定延迟执行:" + System.currentTimeMillis());
// 模拟耗时操作
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
// 使用Cron表达式:每天上午9:30执行
@Scheduled(cron = "0 30 9 * * ?")
public void dailyReport() {
System.out.println("每日报告生成:" + System.currentTimeMillis());
}
// 带初始延迟:延迟10秒后,再每2秒执行一次
@Scheduled(fixedRate = 2000, initialDelay = 10000)
public void delayedTask() {
System.out.println("延迟后执行:" + System.currentTimeMillis());
}
}
注意事项:
- 默认所有任务共用一个线程池(线程数为1),可通过配置修改
- 方法不能有参数,返回类型为void
配置线程池(可选)
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import java.util.concurrent.Executors;
@Configuration
public class SchedulerConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
// 设置线程池大小,避免一个任务阻塞其他任务
taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
}
}
分布式场景:Redis + Redisson的分布式调度
适合多实例部署的微服务,避免任务重复执行。
import org.redisson.api.RScheduledExecutorService;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class DistributedScheduler {
@Autowired
private RedissonClient redissonClient;
public void scheduleDistributedTask() {
RScheduledExecutorService executor = redissonClient.getExecutorService("myTasks");
// 提交一个延迟任务,只会被一个实例执行
executor.schedule(() -> {
System.out.println("分布式定时任务执行,当前实例:" + System.currentTimeMillis());
// 业务逻辑
}, 10, java.util.concurrent.TimeUnit.SECONDS);
}
}
选择建议
| 场景 | 推荐方案 |
|---|---|
| 简单单次/固定周期任务 | Timer 或 ScheduledExecutorService |
| Spring Boot项目,简单任务 | @Scheduled 注解 |
| 复杂调度(Cron表达式) | Spring Boot + Quartz |
| 大规模、高可用分布式系统 | Quartz集群 或 分布式调度框架(xxl-job, Elastic-Job) |
| 微服务多实例防重复执行 | Redis分布式锁 + @Scheduled |
我个人最推荐 Spring Boot的 @Scheduled 注解,简单高效,日常80%的需求都能满足,如果需要Cron表达式支持复杂调度,配合Quartz是业界标准方案。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播