Java实现定时任务的三种⽅法
⽬录
1、 sleep
2、Timer
3、ScheduledExecutorService
总结
是的,不⽤任何框架,⽤我们朴素的 Java 编程语⾔就能实现定时任务。
今天,栈长就介绍 3 种实现⽅法,教你如何使⽤ JDK 实现定时任务!
1、 sleep
这也是我们最常⽤的 sleep 休眠⼤法,不只是当作休眠⽤,我们还可以利⽤它很轻松的能实现⼀个简单的定时任务。
实现逻辑:
新开⼀个线程,添加⼀个 for/ while 死循环,然后在死循环⾥⾯添加⼀个 sleep 休眠逻辑,让程序每隔 N 秒休眠再执⾏⼀次,这样就达到了⼀个简单定时任务的效果。
实现代码如下:
private static void sleepTask() {
new Thread(() -> {
while (true) {
System.out.println("hi, 欢迎关注:Java技术栈");
try {
// 每隔3秒执⾏⼀次
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
这种⽅式⽐较傻⽠化了,只能按固定频率运⾏,不能指定具体运⾏的时间。
另外,上⾯的箭头语法,栈长使⽤了 JDK 8 中的 Lambda 表达式,这⾥就不再撰述了,Java 8 系列实战教程我都写了⼀堆了,不清楚的可以关注:Java技术栈,在后台回复 "java" 阅读,我都整理好了。
2、Timer
来看下 JDK ⾃带的 java.util.Timer 类:
JDK 1.3 就内置了 java.util.Timer 类,可以⽤来调度 java.util.TimerTask 任务。
⼏个重要的⽅法:
schedule:开始调度任务,提供了⼏个包装⽅法;
cancle:终⽌任务调度,取消当前调度的所有任务,正在运⾏的任务不受影响;
purge:从任务队列中移除所有已取消的任务;
另外,java.util.TimerTask 就是实现了 Runnable 接⼝,具体任务逻辑则是在 run ⽅法⾥去实现。
实现代码如下:
private static void timerTask() throws InterruptedException {
Timer timer = new Timer();
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
System.out.println("hi, 欢迎关注:Java技术栈");
}
};
// 第⼀次任务延迟时间
long delay = 2000;
// 任务执⾏频率
long period = 3 * 1000;
// 开始调度
timer.schedule(timerTask, delay, period);
// 指定⾸次运⾏时间
// timer.schedule(timerTask, DateUtils.addSeconds(new Date(), 5), period);
Thread.sleep(20000);
/
/ 终⽌并移除任务
timer.cancel();
timer.purge();
}
这种实现⽅式⽐较简单,可以指定⾸次执⾏的延迟时间、⾸次执⾏的具体⽇期时间,以及执⾏频率,能满⾜⽇常需要。
另外,需要注意的是,Timer 是线程安全的,因为背后是单线程在执⾏所有任务。
Timer 也会有⼀些缺陷:
Timer 是单线程的,假如有任务 A,B,C,任务 A 如果执⾏时间⽐较长,那么就会影响任务 B,C 的启动和执⾏时间,如果B,C 执⾏时间也⽐较长,那就会相互影响;
Timer 不会捕获异常,如果 A,B,C 任何⼀个任务在执⾏过程中发⽣异常,就会导致 TImer 整个定时任务停⽌⼯作;
Timer 是基于绝对时间调度的,⽽不是基于相对时间,所以它对系统时间的改变⾮常敏感;
所以,如果在使⽤ Timer 的过程中要注意这些缺陷,虽然可以⽤,但不推荐。
3、ScheduledExecutorService
java技术栈图因 Timer 有⼀些缺陷,所以不太建议使⽤ Timer,推荐使⽤ ScheduledExecutorService:
ScheduledExecutorService 即是 Timer 的替代者,JDK 1.5 并发包引⼊,是基于线程池设计的定时任务类:wScheduledThreadPool
上了线程池,每个调度任务都会分配到线程池中的某⼀个线程去执⾏,任务就是并发调度执⾏的,任务之间互不影响。
⼏个重要的调度⽅法:
schedule:只执⾏⼀次调度;
scheduleAtFixedRate:按固定频率调度,如果执⾏时间过长,下⼀次调度会延迟,不会同时执⾏;
scheduleWithFixedDelay:延迟调度,上⼀次执⾏完再加上延迟时间后执⾏;
另外,可以看出,任务是⽀持 Runnable 和 Callable 调度的。
实现代码如下:
public static void poolTask(){
ScheduledExecutorService pool = wScheduledThreadPool(10);
pool.scheduleAtFixedRate(() -> {
System.out.println("hi, 欢迎关注:Java技术栈");
}, 2000, 3000, TimeUnit.MILLISECONDS);
}
这是⼀个按固定频率调度的任务,创建了 10 个核⼼线程数,⾸次执⾏延迟 2 秒,后续每 3 秒执⾏⼀次。
这种⽅式简单、好⽤,避免了使⽤ Timer 带来的各种问题,推荐使⽤这种实现⽅式。
总结
好了,本⽂栈长分享了 3 种 Java 实现定时任务的⽅式,也相对简单,但执⾏频率时间设置都太简单,只适合简单的业务,不适合实际复杂业务的需求,实际业务要考虑分布式、故障转移恢复等远要复杂的多。
本⽂仅给⼤家⼀个参考吧,在不⽤框架的前提下也能实现定时任务,在⼩⽽美的场景,还是很⾹的。
最后,Java 系列教程还会继续更新,关注Java技术栈第⼀时间推送,还可以在菜单中获取历史 Java 教程,都是⼲货。
本节教程所有实战源码已上传到这个仓库:
最后,觉得我的⽂章对你⽤收获的话,动动⼩⼿,给个在看、转发,原创不易,栈长需要你的⿎励。
以上就是Java 实现定时任务的三种⽅法的详细内容,更多关于Java 实现定时任务的资料请关注其它相关⽂章!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。