本文目录导读:

- Timer + TimerTask(基础版)
- ScheduledExecutorService(推荐使用)
- Quartz框架(企业级)
- Spring @Scheduled(最常见)
- 线程池定时任务配置
- 实用示例:数据备份
- Cron表达式速查表
- 选择建议
我来为你提供几个Java定时任务的经典案例,从简单到复杂。
Timer + TimerTask(基础版)
import java.util.Timer;
import java.util.TimerTask;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TimerExample {
public static void main(String[] args) {
Timer timer = new Timer("MyTimer");
// 1. 延迟2秒后执行
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("延迟2秒执行: " + getCurrentTime());
}
}, 2000);
// 2. 延迟3秒后,每隔1秒执行一次
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("定时任务执行: " + getCurrentTime());
}
}, 3000, 1000);
// 3. 指定日期执行
Date scheduledTime = new Date(System.currentTimeMillis() + 5000);
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("指定日期执行: " + getCurrentTime());
}
}, scheduledTime);
// 4. 取消任务
TimerTask task = new TimerTask() {
@Override
public void run() {
System.out.println("这个任务会在3秒后取消");
}
};
timer.schedule(task, 1000, 1000);
// 5秒后取消特定任务
timer.schedule(new TimerTask() {
@Override
public void run() {
task.cancel();
System.out.println("已取消任务 - " + getCurrentTime());
}
}, 5000);
}
private static String getCurrentTime() {
return new SimpleDateFormat("HH:mm:ss").format(new Date());
}
}
ScheduledExecutorService(推荐使用)
import java.util.concurrent.*;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ScheduledExecutorExample {
public static void main(String[] args) throws InterruptedException {
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(3);
// 1. 一次性任务 - 延迟3秒执行
ScheduledFuture<?> oneTime = scheduler.schedule(() -> {
System.out.println("一次性任务执行: " + getTime());
}, 3, TimeUnit.SECONDS);
// 2. 固定速率执行 - 每2秒执行一次
ScheduledFuture<?> fixedRate = scheduler.scheduleAtFixedRate(() -> {
System.out.println("固定速率任务: " + getTime());
}, 1, 2, TimeUnit.SECONDS);
// 3. 固定延迟执行 - 上次执行完成后延迟1秒再执行
ScheduledFuture<?> fixedDelay = scheduler.scheduleWithFixedDelay(() -> {
try {
Thread.sleep(2000); // 模拟耗时操作
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("固定延迟任务: " + getTime() + " (耗时2秒)");
}, 1, 1, TimeUnit.SECONDS);
// 4. 复杂任务 - 支持返回值
ScheduledFuture<Integer> result = scheduler.schedule(() -> {
System.out.println("返回结果任务执行");
return 42;
}, 4, TimeUnit.SECONDS);
// 获取任务返回值
try {
Integer value = result.get(5, TimeUnit.SECONDS);
System.out.println("任务返回值: " + value);
} catch (Exception e) {
e.printStackTrace();
}
// 运行8秒后关闭
Thread.sleep(8000);
scheduler.shutdown();
System.out.println("调度器已关闭");
}
private static String getTime() {
return new SimpleDateFormat("HH:mm:ss").format(new Date());
}
}
Quartz框架(企业级)
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.text.SimpleDateFormat;
import java.util.Date;
public class QuartzExample {
// 自定义任务类
public static class MyJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
JobDataMap dataMap = context.getJobDetail().getJobDataMap();
String name = dataMap.getString("name");
System.out.println("Quartz任务执行 - " + name + ", 时间: " + getTime());
}
}
public static void main(String[] args) throws SchedulerException {
// 1. 创建Scheduler
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 2. 创建Job
JobDetail job = JobBuilder.newJob(MyJob.class)
.withIdentity("myJob", "group1")
.usingJobData("name", "定时任务-1")
.build();
// 3. 创建Trigger - cron表达式
Trigger cronTrigger = TriggerBuilder.newTrigger()
.withIdentity("myTrigger", "group1")
.startNow()
.withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))
.build();
// 4. 创建简单Trigger
Trigger simpleTrigger = TriggerBuilder.newTrigger()
.withIdentity("simpleTrigger", "group1")
.startAt(new Date(System.currentTimeMillis() + 3000))
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(2)
.repeatForever())
.build();
// 5. 创建Trigger - 每天特定时间执行
Trigger dailyTrigger = TriggerBuilder.newTrigger()
.withIdentity("dailyTrigger", "group1")
.startNow()
.withSchedule(CronScheduleBuilder
.cronSchedule("0 30 9 * * ?")) // 每天9:30执行
.build();
// 注册任务和触发器
scheduler.scheduleJob(job, cronTrigger);
scheduler.scheduleJob(job, simpleTrigger);
// 如果同一个Job有多个Trigger,需要这样处理:
JobDetail job2 = JobBuilder.newJob(MyJob.class)
.withIdentity("myJob2", "group1")
.usingJobData("name", "每日定时任务")
.build();
scheduler.scheduleJob(job2, dailyTrigger);
// 启动调度器
scheduler.start();
System.out.println("Quartz调度器已启动");
// 10秒后关闭
new Thread(() -> {
try {
Thread.sleep(10000);
scheduler.shutdown();
System.out.println("Quartz调度器已关闭");
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
private static String getTime() {
return new SimpleDateFormat("HH:mm:ss").format(new Date());
}
}
Spring @Scheduled(最常见)
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
@SpringBootApplication
@EnableScheduling // 开启定时任务
public class SpringSchedulingApplication {
public static void main(String[] args) {
SpringApplication.run(SpringSchedulingApplication.class, args);
}
}
@Component
class ScheduledTasks {
private final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
// 1. 固定速率执行 - 每2秒执行一次
@Scheduled(fixedRate = 2000)
public void fixedRateTask() throws InterruptedException {
System.out.println("固定速率任务 [每2秒] - " + dateFormat.format(new Date()));
Thread.sleep(1000); // 模拟耗时操作
}
// 2. 固定延迟执行 - 上次完成后延迟1秒
@Scheduled(fixedDelay = 1000)
public void fixedDelayTask() throws InterruptedException {
System.out.println("固定延迟任务 [完成后1秒] - " + dateFormat.format(new Date()));
Thread.sleep(1500);
}
// 3. 初始延迟2秒,然后每3秒执行一次
@Scheduled(initialDelay = 2000, fixedRate = 3000)
public void initialDelayTask() {
System.out.println("延迟启动任务 [延迟2秒,每3秒] - " + dateFormat.format(new Date()));
}
// 4. Cron表达式 - 每分钟执行一次
@Scheduled(cron = "0 * * * * ?")
public void cronTask() {
System.out.println("Cron任务 [每分钟] - " + dateFormat.format(new Date()));
}
// 5. Cron表达式 - 工作日每天9点执行
@Scheduled(cron = "0 0 9 * * MON-FRI")
public void workdayTask() {
System.out.println("工作日任务 [周一至周五9点] - " + dateFormat.format(new Date()));
}
// 6. 国庆节每天执行
@Scheduled(cron = "0 0 10 1-7 10 ?")
public void holidayTask() {
System.out.println("国庆节任务 [10月1-7日10点] - " + dateFormat.format(new Date()));
}
}
// 配置文件方式(application.properties)
// spring.task.scheduling.pool.size=10
// spring.task.scheduling.thread-name-prefix=scheduling-
线程池定时任务配置
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
@Configuration
public class SchedulingConfig {
// 自定义线程池配置
@Bean
public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(10);
scheduler.setThreadNamePrefix("my-scheduler-");
scheduler.setWaitForTasksToCompleteOnShutdown(true);
scheduler.setAwaitTerminationSeconds(30);
scheduler.initialize();
return scheduler;
}
// 使用Spring的ScheduledExecutorService
@Bean
public ScheduledExecutorService scheduledExecutorService() {
ThreadFactory factory = new ThreadFactory() {
private final AtomicInteger counter = new AtomicInteger();
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setName("custom-pool-" + counter.incrementAndGet());
thread.setDaemon(false);
return thread;
}
};
return Executors.newScheduledThreadPool(5, factory);
}
}
实用示例:数据备份
import java.util.concurrent.*;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DataBackupScheduler {
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
public void startBackupTasks() {
// 每天凌晨2点备份
scheduleBackup();
// 每周一清理日志
scheduleLogCleanup();
// 每小时监控系统状态
scheduleHealthCheck();
}
private void scheduleBackup() {
scheduler.scheduleWithFixedDelay(() -> {
System.out.println("[备份任务] 开始备份数据库 - " + getTime());
try {
// 模拟备份操作
Thread.sleep(3000);
System.out.println("[备份任务] 备份完成 - " + getTime());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}, 0, 24 * 60 * 60, TimeUnit.SECONDS); // 每24小时执行一次
}
private void scheduleLogCleanup() {
scheduler.schedule(() -> {
System.out.println("[清理任务] 开始清理日志文件 - " + getTime());
// 模拟清理操作
try {
Thread.sleep(2000);
System.out.println("[清理任务] 日志清理完成 - " + getTime());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}, 7 * 24 * 60 * 60, TimeUnit.SECONDS); // 7天后执行
}
private void scheduleHealthCheck() {
scheduler.scheduleAtFixedRate(() -> {
System.out.println("[监控任务] 系统检查 - " + getTime() + " CPU使用率: " +
(Math.random() * 50 + 20) + "%");
}, 0, 1, TimeUnit.HOURS); // 每小时检查
}
private String getTime() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
}
public static void main(String[] args) {
DataBackupScheduler backupSystem = new DataBackupScheduler();
backupSystem.startBackupTasks();
System.out.println("备份系统已启动,按任意键退出...");
}
}
Cron表达式速查表
public class CronExpressions {
// 语法: 秒 分 时 日 月 周 年(可选)
public static final String EVERY_SECOND = "*/1 * * * * ?";
public static final String EVERY_MINUTE = "0 * * * * ?";
public static final String EVERY_HOUR = "0 0 * * * ?";
public static final String EVERY_DAY_MIDNIGHT = "0 0 0 * * ?";
public static final String WEEKDAY_9AM = "0 0 9 * * MON-FRI";
public static final String WEEKEND_10AM = "0 0 10 * * SAT,SUN";
public static final String MONTHLY_FIRST_DAY = "0 0 0 1 * ?";
public static final String EVERY_5_MINUTES = "0 */5 * * * ?";
public static final String SPECIFIC_TIME = "0 30 14 * * ?"; // 每天14:30
public static String getDescription(String cron) {
// 这里可以添加解析逻辑
return "Cron表达式: " + cron;
}
}
选择建议
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 简单任务 | Timer |
轻量级,但功能有限 |
| 企业应用 | ScheduledExecutorService |
线程池支持,更可靠 |
| Spring项目 | @Scheduled |
易用优雅,功能强大 |
| 复杂调度 | Quartz |
分布式、持久化、复杂Cron |
| 分布式任务 | XXL-Job / ElasticJob |
集群、可视化、高可用 |
这些示例涵盖了主流的使用场景,你可以根据项目需求选择合适的实现方式。