发布于2026-07-15 阅读(0)
扫一扫,手机访问
Ja va实现定时任务,在开发中算是一个高频需求了。虽然JDK本身提供了多种方案,但在实际项目中,到底选哪一种、怎么用更合理,还是有讲究的。下面把这几种常见方式拆开来看,从基础工具到框架集成,一步步说清楚。
Timer和TimerTask是ja va.util包下的原生类,专门用来处理定时任务。使用起来非常直接:
TimerTask实现了Runnable接口,所以它的实例本质上就是一个可执行的任务。Timer中提供了两个核心方法来调度任务:schedule()和scheduleAtFixedRate()。
void schedule(TimerTask task, Date time)
在指定的时间点执行一次任务。如果那个时间已经过去了,任务会立即执行。
void schedule(TimerTask task, long delay)
延迟指定毫秒数后执行一次任务。
void schedule(TimerTask task, long delay, long period)
延迟delay毫秒后,每period毫秒周期性地执行任务。
public void schedule(TimerTask task, Date firstTime, long period)
从firstTime指定时间开始,每period毫秒执行一次。
void scheduleAtFixedRate(TimerTask task, long delay, long period)
延迟delay毫秒后,按固定频率每period毫秒执行一次。
void scheduleAtFixedRate(TimerTask task, Date firstTime,long period)
从firstTime指定时间开始,按固定频率每period毫秒执行一次。
看个完整案例:
import ja va.util.Date;
import ja va.util.Timer;
import ja va.util.TimerTask;
public class TimerExample {
public static void main(String[] args) {
Timer timer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
System.out.println("Hello world!");
}
};
timer.schedule(task, new Date()); // 立即执行一次
timer.schedule(task, 1000); // 1秒后执行一次
timer.schedule(task, new Date(), 2000); // 每2秒执行一次
timer.schedule(task, 2000, 2000); // 2秒后每2秒执行一次
timer.scheduleAtFixedRate(task, 3000, 3000); // 3秒后每3秒执行一次
timer.scheduleAtFixedRate(task, new Date(), 4000); // 每3秒执行一次
}
}
Ja va线程池体系中有一个专门用来执行定时任务的类——ScheduledExecutorService。它提供了三个核心方法:
其中TimeUnit是一个枚举,用来指定时间单位,比如NANOSECONDS、MICROSECONDS、MILISECONDS、SECONDS、MINUTES、HOURS、DAYS等。与Timer相比,ScheduledExecutorService的方法多了一个返回值,类型是ScheduledFuture,这在需要取消任务或获取结果时非常有用。
public ScheduledFuture> schedule(Runnable command, long delay, TimeUnit unit)
延迟指定时间单位后执行一次任务。
publicScheduledFuture schedule(Callable callable, long delay, TimeUnit unit)
延迟指定时间单位后执行一次Callable任务,并返回结果。
public ScheduledFuture> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
延迟initialDelay个时间单位后,按period个时间单位固定频率执行。
public ScheduledFuture> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)
延迟initialDelay后,每次任务执行完后等待delay个时间单位再执行下一次。
案例代码:
import ja va.util.concurrent.Callable;
import ja va.util.concurrent.Executors;
import ja va.util.concurrent.ScheduledExecutorService;
import ja va.util.concurrent.TimeUnit;
public class ScheduledExecutorServiceExample {
public static void main(String[] args) {
Runnable task = new Runnable() {
@Override
public void run() {
System.out.println("Hello world!");
}
};
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2);
scheduledThreadPool.schedule(task, 3, TimeUnit.SECONDS); // 3秒后执行一次
scheduledThreadPool.schedule(new Callable
如果项目用了Spring Boot,那么Spring Task是最省心的方案。只需要两步:
第一步:在启动类上添加@EnableScheduling注解,开启定时任务支持。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@EnableScheduling
@SpringBootApplication
public class TimerApplication {
public static void main(String[] args) {
SpringApplication.run(TimerApplication.class, args);
}
}
第二步:创建一个组件,在方法上添加@Scheduled注解,并通过cron属性指定执行时间。
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class TimerTask {
/**
* cron属性指定在每年的7月18日12:55:00执行一次定时任务
*/
@Scheduled(cron = "0 55 12 18 7 *")
public void task() {
System.out.println("执行定时任务...");
}
}
时间一到,控制台就会输出结果。

Quartz是一个功能更强大的任务调度框架,Spring Boot对其有很好的集成支持。步骤如下:
第一步:在pom.xml中添加依赖。
org.springframework.boot spring-boot-starter-quartz
第二步:创建一个任务类,实现Job接口。
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.springframework.stereotype.Component;
@Component
public class QuartzJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) {
System.out.println("执行QuartzJob定时任务...");
}
}
第三步:配置任务触发条件。用JobDetail绑定任务类,用Trigger定义触发规则(比如Cron表达式)。
import org.quartz.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class QuartzConfig {
@Bean
public JobDetail jobDetail() {
return JobBuilder.newJob(QuartzJob.class)
.withIdentity("quartzJob")
.storeDurably()
.build();
}
@Bean
public Trigger trigger(JobDetail jobDetail) {
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/10 * * * * ?");
return TriggerBuilder.newTrigger()
.forJob(jobDetail)
.withIdentity("trigger")
.withSchedule(cronScheduleBuilder)
.build();
}
}
从原生的Timer到线程池的ScheduledExecutorService,再到Spring Task和Quartz,每种方案都有各自的适用场景。Timer简单但缺少线程池管理能力,ScheduledExecutorService灵活且可靠,Spring Task开箱即用,Quartz则适合复杂的企业级调度需求。掌握这些,日常开发中的定时任务基本都能覆盖了。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8