Java语言自带了定时调度功能,它通常出现在业务调度中,在规定的时间内运行业务流程
实现功能的是Java的util包下的两个类
import java.util.Timer;
import java.util.TimerTask;
其实地底层跑的就是定时线程池Thread,有兴趣的可以去看看源码,用的时候如下
import java.util.Timer;
import java.util.TimerTask;
public class TExt {
public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("2秒后开始执行任务,之后每5秒执行一次");
}
},2000,5000);
}
}
写法和运作流程有点像定时线程,schedule方法第一个参数直接用内部类就行,run中写业务流程,第二参数是第一次执行任务时间,就是在程序跑起来之后多长时间进行第一次运行,时间单位是毫秒,第三个参数是第一次之后,从第二次开始每隔多长时间运行一次任务,时间单位也是毫秒
当然timer.schedule还有其他的API
public void schedule(TimerTask task, long delay)
调度一个task,经过delay(ms)后开始进行调度,仅仅调度一次
public void schedule(TimerTask task, Date time)
在指定的时间点time上调度一次
public void schedule(TimerTask task, long delay, long period)
调度一个task,在delay(ms)后开始调度第一次,第一次调度完后,往后调度均为等待period(ms)后开始调度
public void schedule(TimerTask task, Date firstTime, long period)
和上一个方法区别就是传入的第二个参数为第一次调度的时间,这个时间是一个date对象
public void scheduleAtFixedRate(TimerTask task, long delay, long period)
这个方法有别于schedule,schedule用的是理论调度时间,也就是说它的调度时间是在程序开始之后就确定的,如2秒后执行第一次,之后每5秒执行一次,那么schedule就会严格2,7,12这样的时间线去跑任务,但是如果某一时刻,因为cpu或者其他问题任务的运行实际时间就会不一样,这会导致任务冲突等种种麻烦的问题,而scheduleAtFixedRate是用每一次任务的实际运行时间去决定下一次任务在上面时间去执行的,也就是指该方法的调度时间是由上一次实际结束时间加上间隔时间决定下一次执行时间
public void scheduleAtFixedRate(TimerTask task, Date firstTime,long period)
和上一方法一样,第二个参数是一个date对象
当然如果你没有很特殊的要求,用完就可以直接调用定时线程的类。
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class SchedulerExample {
public static void main(String[] args) {
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
// 延迟任务
scheduler.schedule(
() -> System.out.println("五秒后执行一次任务!"),
5, TimeUnit.SECONDS
);
// 固定频率任务
scheduler.scheduleAtFixedRate(
() -> System.out.println("两秒后第1次执行,往后每三秒执行一次"),
2, 3, TimeUnit.SECONDS
);
// 如果第1次执行时间大于周期时间,那么。第1次的延迟时间将会失效,以周期时间看齐。
scheduler.scheduleWithFixedDelay(
() -> {
try {
Thread.sleep(1000); // 模拟任务耗时
System.out.println("固定延迟任务");
} catch (InterruptedException e) {
e.printStackTrace();
}
},
2, 1, TimeUnit.SECONDS
);
// 关闭线程池(示例运行10秒后关闭)
scheduler.schedule(
() -> {
System.out.println("关闭线程池...");
scheduler.shutdown();
},
10, TimeUnit.SECONDS
);
}
}