Java实现定时任务的几种常见方式
精心整理了最新的面试资料和简历模板,有需要的可以自行获取
点击前往百度网盘获取
点击前往夸克网盘获取
一、基础线程 + sleep
方法
原理:通过循环和线程休眠实现简单定时任务。
public class SimpleTimer {public static void main(String[] args) {Runnable task = () -> {while (true) {try {// 任务逻辑System.out.println("Task executed at " + new Date());Thread.sleep(5000); // 每5秒执行一次} catch (InterruptedException e) {e.printStackTrace();break;}}};new Thread(task).start();}
}
缺点:精度低、资源占用高,不推荐生产环境使用。
二、Timer
和 TimerTask
原理:Java原生工具类,支持单线程调度任务。
import java.util.Timer;
import java.util.TimerTask;public class TimerDemo {public static void main(String[] args) {TimerTask task = new TimerTask() {@Overridepublic void run() {System.out.println("TimerTask executed at " + new Date());}};Timer timer = new Timer();// 延迟1秒后执行,每3秒重复一次timer.scheduleAtFixedRate(task, 1000, 3000);}
}
缺点:单线程执行,任务异常会导致后续任务终止。
三、ScheduledExecutorService
原理:线程池增强版,支持多线程和更灵活的调度。
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;public class ExecutorServiceDemo {public static void main(String[] args) {ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);Runnable task = () -> {System.out.println("Executor task at " + new Date());};// 延迟2秒后启动,每5秒执行一次executor.scheduleAtFixedRate(task, 2, 5, TimeUnit.SECONDS);}
}
优点:线程池管理、支持异常处理。
四、Spring 的 @Scheduled
注解
原理:Spring框架提供,通过注解简化配置。
- 启用定时任务(配置类):
@Configuration
@EnableScheduling
public class SpringConfig {}
- 定义定时任务类:
@Component
public class SpringTaskDemo {@Scheduled(fixedRate = 5000) // 每5秒执行一次public void scheduledTask() {System.out.println("Spring task at " + new Date());}@Scheduled(cron = "0 0 12 * * ?") // 每天中午12点执行public void cronTask() {System.out.println("Cron task executed.");}
}
需配置线程池(避免单线程阻塞):
# application.properties
spring.task.scheduling.pool.size=5
五、Quartz 框架
原理:企业级调度框架,支持复杂调度规则和持久化。
- 添加依赖:
<dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.3.2</version>
</dependency>
- 实现任务逻辑:
public class QuartzJob implements Job {@Overridepublic void execute(JobExecutionContext context) {System.out.println("Quartz job executed at " + new Date());}
}
- 配置调度器:
public class QuartzDemo {public static void main(String[] args) throws SchedulerException {JobDetail job = JobBuilder.newJob(QuartzJob.class).withIdentity("myJob").build();Trigger trigger = TriggerBuilder.newTrigger().withIdentity("myTrigger").startNow().withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(10).repeatForever()).build();Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();scheduler.scheduleJob(job, trigger);scheduler.start();}
}
优势:分布式调度、持久化存储、动态配置。
六、对比与总结
方式 | 适用场景 | 优点 | 缺点 |
---|---|---|---|
基础线程 | 简单测试 | 无需依赖库 | 精度低、资源浪费 |
Timer | 单任务轻量级调度 | 原生支持 | 单线程、异常敏感 |
ScheduledExecutor | 多任务需求 | 线程池管理、灵活性强 | 需手动管理生命周期 |
Spring @Scheduled | Spring项目 | 配置简单、集成方便 | 依赖Spring框架 |
Quartz | 企业级复杂调度 | 功能强大、支持持久化/分布式 | 配置复杂、依赖库较多 |
选择建议:
- 简单任务:优先选择
ScheduledExecutorService
或 Spring@Scheduled
- 复杂调度(如分布式):使用 Quartz
- 避免使用
Timer
和基础线程方案
可根据项目规模和技术栈灵活选择最适合的方案。