本文目录导读:

- Timer + TimerTask(简单方案)
- ScheduledExecutorService(推荐方案)
- Spring @Scheduled(企业级方案)
- 完整的清理实现示例(结合数据库)
- 使用Quartz(分布式场景)
- 最佳实践建议
在Java中实现定时清理数据的常见方案有以下几种,我会从简单到复杂逐一介绍:
Timer + TimerTask(简单方案)
适用于简单场景,单线程执行:
import java.util.Timer;
import java.util.TimerTask;
public class DataCleanupExample {
public static void main(String[] args) {
Timer timer = new Timer("DataCleanupTimer");
// 延迟1秒后开始,每24小时执行一次
timer.schedule(new TimerTask() {
@Override
public void run() {
cleanExpiredData();
}
}, 1000, 24 * 60 * 60 * 1000);
// 或者使用相对时间
// timer.schedule(new TimerTask() { ... }, new Date(), period);
}
private static void cleanExpiredData() {
System.out.println("开始清理过期数据...");
// 实际清理逻辑
// 比如删除7天前的日志
// DELETE FROM logs WHERE create_time < DATE_SUB(NOW(), INTERVAL 7 DAY)
}
}
ScheduledExecutorService(推荐方案)
这是JDK推荐的方案,支持多线程:
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ScheduledCleanupExample {
private final ScheduledExecutorService scheduler;
public ScheduledCleanupExample() {
// 创建线程池,通常1-2个线程就够
this.scheduler = Executors.newScheduledThreadPool(2);
}
public void startCleanupTask() {
// 初始延迟1秒,每30分钟执行一次
scheduler.scheduleAtFixedRate(() -> {
try {
performCleanup();
} catch (Exception e) {
// 异常处理,避免任务停止
System.err.println("清理任务失败: " + e.getMessage());
}
}, 1, 30, TimeUnit.MINUTES);
}
private void performCleanup() {
System.out.println("[" + new java.util.Date() + "] 执行数据清理...");
// 示例:清理7天前的数据
cleanupOldRecords("logs", 7);
cleanupOldRecords("temp_files", 3);
}
private void cleanupOldRecords(String table, int days) {
// 实际数据库操作
// String sql = "DELETE FROM " + table + " WHERE create_time < ?";
// jdbcTemplate.update(sql, new java.util.Date(System.currentTimeMillis() -
// (long) days * 24 * 60 * 60 * 1000));
System.out.println("清理表 " + table + " 中" + days + "天前的数据");
}
public void shutdown() {
scheduler.shutdown();
try {
if (!scheduler.awaitTermination(60, TimeUnit.SECONDS)) {
scheduler.shutdownNow();
}
} catch (InterruptedException e) {
scheduler.shutdownNow();
Thread.currentThread().interrupt();
}
}
public static void main(String[] args) {
ScheduledCleanupExample example = new ScheduledCleanupExample();
example.startCleanupTask();
// 程序运行时保持运行
Runtime.getRuntime().addShutdownHook(new Thread(example::shutdown));
}
}
Spring @Scheduled(企业级方案)
如果你的项目使用Spring框架,这是最简单的方式:
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
@EnableScheduling
public class ScheduledDataCleanup {
// 每天凌晨2点执行
@Scheduled(cron = "0 0 2 * * ?")
public void cleanupDailyData() {
System.out.println("执行每日数据清理...");
// 清理逻辑
}
// 每30分钟执行一次
@Scheduled(fixedRate = 30 * 60 * 1000)
public void cleanupTempData() {
System.out.println("清理临时数据...");
// 清理逻辑
}
// 上次执行完后延迟10分钟再执行
@Scheduled(fixedDelay = 600000)
public void cleanupAfterPrevious() {
System.out.println("上次清理完成后10分钟再执行...");
}
// 带初始延迟的任务
@Scheduled(initialDelay = 5000, fixedRate = 3600000)
public void cleanupWithDelay() {
// 启动5秒后,每小时执行一次
}
}
完整的清理实现示例(结合数据库)
import java.sql.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class DatabaseDataCleanup {
private static final String DB_URL = "jdbc:mysql://localhost:3306/mydb";
private static final String DB_USER = "root";
private static final String DB_PASS = "password";
public void cleanOldRecords() {
String sql = "DELETE FROM user_logs WHERE create_time < ?";
try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASS);
PreparedStatement pstmt = conn.prepareStatement(sql)) {
// 设置7天前的时间
LocalDateTime cutoffDate = LocalDateTime.now().minusDays(7);
pstmt.setObject(1, cutoffDate);
int deletedCount = pstmt.executeUpdate();
System.out.println("清理了 " + deletedCount + " 条过期记录");
} catch (SQLException e) {
System.err.println("数据库清理失败: " + e.getMessage());
}
}
// 批量清理,避免大事务
public void batchCleanup() {
int batchSize = 1000;
String sql = "DELETE FROM logs WHERE create_time < ? LIMIT ?";
try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASS);
PreparedStatement pstmt = conn.prepareStatement(sql)) {
LocalDateTime cutoffDate = LocalDateTime.now().minusDays(30);
int totalDeleted = 0;
while (true) {
pstmt.setObject(1, cutoffDate);
pstmt.setInt(2, batchSize);
int deleted = pstmt.executeUpdate();
totalDeleted += deleted;
if (deleted < batchSize) {
break; // 没有更多数据可删除
}
// 稍微暂停,避免数据库压力过大
Thread.sleep(100);
}
System.out.println("总共清理了 " + totalDeleted + " 条记录");
} catch (SQLException | InterruptedException e) {
System.err.println("批量清理失败: " + e.getMessage());
}
}
}
使用Quartz(分布式场景)
对于分布式系统,推荐使用Quartz框架:
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
public class QuartzCleanupExample {
public static void main(String[] args) throws SchedulerException {
// 1. 定义Job
JobDetail job = JobBuilder.newJob(CleanupJob.class)
.withIdentity("dataCleanupJob", "cleanupGroup")
.build();
// 2. 定义触发器(每天凌晨3点)
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("cleanupTrigger", "cleanupGroup")
.withSchedule(CronScheduleBuilder.cronSchedule("0 0 3 * * ?"))
.build();
// 3. 启动调度器
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.start();
scheduler.scheduleJob(job, trigger);
}
}
// 自定义Job
class CleanupJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("执行定时清理任务...");
// 清理逻辑
}
}
最佳实践建议
-
选择合适的方案:
- 简单应用:
ScheduledExecutorService - Spring应用:
@Scheduled - 分布式系统:
Quartz或XXL-JOB
- 简单应用:
-
异常处理:确保任务不会因为一次失败就停止
-
日志记录:记录清理的开始、结束和执行情况
-
幂等性设计:确保多次执行结果一致
-
分批处理:大量数据时避免大事务
-
监控告警:清理失败时要能及时发现
选择哪种方案取决于你的项目规模、框架使用情况和业务复杂度。
版权声明: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直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播