Java 中怎么实现一个定时任务,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
实现逻辑:
新开一个线程,添加一个 for/ while 死循环,然后在死循环里面添加一个 sleep 休眠逻辑,让程序每隔 N 秒休眠再执行一次,这样就达到了一个简单定时任务的效果。
实现代码如下:
/** * 休眠实现定时任务 * 来源公众号:Java技术栈 */ 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 表达式,这里就不再撰述了。
2、Timer
来看下 JDK 自带的 java.util.Timer 类:
JDK 1.3 就内置了 java.util.Timer 类,可以用来调度 java.util.TimerTask 任务。
几个重要的方法:
schedule:开始调度任务,提供了几个包装方法;
cancle:终止任务调度,取消当前调度的所有任务,正在运行的任务不受影响;
purge:从任务队列中移除所有已取消的任务;
另外,java.util.TimerTask 就是实现了 Runnable 接口,具体任务逻辑则是在 run 方法里去实现。
实现代码如下:
/** * timer定时任务 * 来源公众号:Java技术栈 */ 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
因 Timer 有一些缺陷,所以不太建议使用 Timer,推荐使用 ScheduledExecutorService:
ScheduledExecutorService 即是 Timer 的替代者,JDK 1.5 并发包引入,是基于线程池设计的定时任务类:
java.util.concurrent.Executors.newScheduledThreadPool
上了线程池,每个调度任务都会分配到线程池中的某一个线程去执行,任务就是并发调度执行的,任务之间互不影响。
几个重要的调度方法:
schedule:只执行一次调度;
scheduleAtFixedRate:按固定频率调度,如果执行时间过长,下一次调度会延迟,不会同时执行;
scheduleWithFixedDelay:延迟调度,上一次执行完再加上延迟时间后执行;
另外,可以看出,任务是支持 Runnable 和 Callable 调度的。
实现代码如下:
/** * 线程池定时任务 * 来源公众号:Java技术栈 */ public static void poolTask(){ ScheduledExecutorService pool = Executors.newScheduledThreadPool(10); pool.scheduleAtFixedRate(() -> { System.out.println("hi, 欢迎关注:Java技术栈"); }, 2000, 3000, TimeUnit.MILLISECONDS); }
关于Java 中怎么实现一个定时任务问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。