Java中实现定时任务的3种方法!

今天我们不用任何框架,用最朴素的 Java API 来实现定时任务,本文会介绍 3 种实现方案,我们一起来看...

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 表达式。

2、Timer

来看下 JDK 自带的 java.util.Timer 类:

JDK 1.3 就内置了 java.util.Timer 类,可以用来调度 java.util.TimerTask 任务。

几个重要的方法:

  • schedule:开始调度任务,提供了几个包装方法;

  • cancle:终止任务调度,取消当前调度的所有任务,正在运行的任务不受影响;

  • purge:从任务队列中移除所有已取消的任务;

另外,java.util.TimerTask 就是实现了 Runnable 接口,具体任务逻辑则是在 run 方法里去实现。

实现代码如下:

/*** timer定时任务*/
private static void timerTask() throws InterruptedException {Timer timer = new Timer();TimerTask timerTask = new TimerTask() {@Overridepublic void run() {System.out.println("hi, 欢迎关注");}};// 第一次任务延迟时间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 调度的。

实现代码如下:

/*** 线程池定时任务*/
public static void poolTask(){ScheduledExecutorService pool = Executors.newScheduledThreadPool(10);pool.scheduleAtFixedRate(() -> {System.out.println("hi, 欢迎关注");}, 2000, 3000, TimeUnit.MILLISECONDS);
}

这是一个按固定频率调度的任务,创建了 10 个核心线程数,首次执行延迟 2 秒,后续每 3 秒执行一次。

这种方式简单、好用,避免了使用 Timer 带来的各种问题,推荐使用这种实现方式。

总结

本文分享了 3 种  Java 实现定时任务的方式,也相对简单,但执行频率时间设置都太简单,只适合简单的业务,不适合实际复杂业务的需求,实际业务要考虑分布式、故障转移恢复等远要复杂的多。

本文仅给大家一个参考吧,在不用框架的前提下也能实现定时任务,在小而美的场景,还是很香的。


往期推荐

定时任务的实现原理,看完就能手撸一个!


一口气说出 6 种延时队列的实现方法,面试官满意的笑了


JDK 9 对字符串 String 的优化,挺有意思!


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/544928.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

回文子序列_计算回文子序列的总数

回文子序列Problem statement: 问题陈述&#xff1a; Given a string str, find total number of possible palindromic sub-sequences. A sub-sequence does not need to be consecutive, but for any xixj i<j must be valid in the parent string too. Like "icl&q…

Zookeeper 的 5 大核心知识点!

1 ZooKeeper简介ZooKeeper 是一个开源的分布式协调框架&#xff0c;它的定位是为分布式应用提供一致性服务&#xff0c;是整个大数据体系的管理员。ZooKeeper 会封装好复杂易出错的关键服务&#xff0c;将高效、稳定、易用的服务提供给用户使用。如果上面的官方言语你不太理解&…

【视频版】最新版Swagger 3升级指南和新功能体验!

作者 | 王磊来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;Swagger 3.0 发布已经有一段时间了&#xff0c;它于 2020.7 月 发布&#xff0c;但目前市面上使用的主流版本还是 Swagger 2…

各大厂面试高频的面试题新鲜出炉,你能答上几道?

关于生产环境如何配置线程数&#xff0c;还是要根据业务来进行区分&#xff0c;我们时常会听到什么IO密集型、CPU密集型任务...那么这里提一个问题&#xff1a;大家知道什么样的任务或者代码会被认定为IO/CPU密集&#xff1f;又是用什么样的标准来认定IO/CPU密集&#xff1f;如…

c/c++如何获取数组的长度

2019独角兽企业重金招聘Python工程师标准>>> C、C中没有提供 直接获取数组长度的函数&#xff0c;对于存放字符串的字符数组提供了一个strlen函数获取长度&#xff0c;那么对于其他类型的数组如何获取他们的长度呢&#xff1f;其中一种方法是使 用sizeof(array) / s…

【送给读者】全新苹果 AirPods,包邮送一套!

为回馈长期以来科创人读者对本栏目的关注支持&#xff0c;本周小编联合了计算机领域八位高质量原创号主一起为大家送出一套 全新苹果AirPods 2代。以下推荐的公号原创率都很高&#xff0c;均为个人IP号&#xff0c;有些小伙伴应该已经关注部分公号。本次抽奖采用第三方抽奖小程…

进程控制(kill)

为什么80%的码农都做不了架构师&#xff1f;>>> kill&#xff1a;终止进程&#xff08;或传送信号到某进程&#xff09; kill [options] [process_ids] kill命令可以发送信号给进程&#xff0c;可以终止&#xff08;terminate&#xff09;&#xff08;默认操作&a…

Swagger增强神器:Knife4j!用它轻松实现接口搜索、Word下载、接口过滤...

视频版内容&#xff1a;Swagger 是开发中最常用的框架之一了&#xff0c;但 Swagger 本身又有很多不完善的地方&#xff0c;比如&#xff0c;在众多的接口中查询某一个接口&#xff0c;又或者是把所有的接口导出成 Word 格式等&#xff0c;都无法在 Swagger 中实现。有人可能会…

7种可能会导致内存泄漏的场景!

虽然Java程序员不用像C/C程序员那样时刻关注内存的使用情况&#xff0c;JVM会帮我们处理好这些&#xff0c;但并不是说有了GC就可以高枕无忧&#xff0c;内存泄露相关的问题一般在测试的时候很难发现&#xff0c;一旦上线流量起来可能马上就是一个诡异的线上故障。1. 内存泄露的…

logstash 过虑nginx访问日志

标题是不是可以翻译成这样&#xff1a;logstash Filters nginx access log好了&#xff0c;进入正题&#xff0c;日志管理服务器我用ElasticSearchLogStashKibanaRedis先说下我的架构&#xff1a;远程NGINX采集日志数据到REDISlogstashelasticsearchkibana服务器至于怎么部署&a…

Spring中的重试功能!嗯,有点东西

来源&#xff1a;https://albenw.github.io/posts/69a9647f/概要Spring实现了一套重试机制&#xff0c;功能简单实用。Spring Retry是从Spring Batch独立出来的一个功能&#xff0c;已经广泛应用于Spring Batch,Spring Integration, Spring for Apache Hadoop等Spring项目。 本…

关于Shell的一些常用命令

2019独角兽企业重金招聘Python工程师标准>>> ls -lat 列出当前目录所有东东的东东 ls -lath 人看的大小 ls -F | grep "/$"只搞目录 ls -lR 包括子目录… ls --ignore filename -lt 忽略某个 which&#xff0c;在PATH变量指定的路径中&#xff0c;搜索看某…

用Netty撸一个心跳机制和断线重连!

来源&#xff1a;www.jianshu.com/p/1a28e48edd92心跳机制何为心跳所谓心跳, 即在 TCP 长连接中, 客户端和服务器之间定期发送的一种特殊的数据包, 通知对方自己还在线, 以确保 TCP 连接的有效性.注&#xff1a;心跳包还有另一个作用&#xff0c;经常被忽略&#xff0c;即&…

ThreadLocal线程范围内的共享变量

模拟ThreadLocal类实现&#xff1a;线程范围内的共享变量&#xff0c;每个线程只能访问他自己的&#xff0c;不能访问别的线程。 package com.ljq.test.thread;import java.util.HashMap; import java.util.Map; import java.util.Random;/*** 线程范围内的共享变量* * 三个模块…

Java中操作Excel的3种方法,太好用了!

一、介绍在平时的业务系统开发中&#xff0c;少不了需要用到导出、导入excel功能&#xff0c;今天我们就一起来总结一下&#xff0c;如果你正为此需求感到困惑&#xff0c;那么阅读完本文&#xff0c;你一定会有所收获&#xff01;二、poi大概在很久很久以前&#xff0c;微软的…

代理服务器Tengine的研究与测试

代理服务器Tengine的研究与测试一、Tengine介绍1.首先要知道什么Nginx1)Nginx&#xff08;发音同 engine x&#xff09;是一款轻量级的Web 服务器&#xff0f;反向代理服务器及电子邮件&#xff08;IMAP/POP3&#xff09;代理服务器&#xff0c;并在一个BSD-like 协议下发行。由…

不错!SpringBoot发布Jar包优化瘦身指南!

概要说明随着Spring Boot的流行&#xff0c;大家体验到只需构建输出一个jar文件&#xff0c;然后只需一个java -jar命令就能部署运行应用的爽快。常见一些单体应用随着项目规模的扩展单个jar文件的大小越来越大&#xff0c;动辄两三百MB。如果再引入微服务架构&#xff0c;动辄…

CountDownLatch:别浪,等人齐再团!

一入王者深似海&#xff0c;从此对象是路人。哈喽观众老爷们大家好&#xff0c;我是战神吕布字奉先&#xff0c;今天给大家来一部吕布的教学视频&#xff01;咳咳&#xff0c;不对。大家好&#xff0c;我是磊哥&#xff0c;今天给大家来一篇 CountDownLatch 的文章。在开始之前…

附彩蛋|Spring Security 竟然故意延长登录时间?知道真相的我惊呆了!

2011年12月21日&#xff0c;有人在网络上公开了一个包含600万个CSDN用户资料的数据库&#xff0c;数据全部为明文储存&#xff0c;包含用户名、密码以及注册邮箱。事件发生后CSDN在微博、官方网站等渠道发出了声明&#xff0c;解释说此数据库系2009年备份所用&#xff0c;因不明…

DirectX 矩阵

基础&#xff1a; 下标&#xff1a;第一个下标为该元素所在行的索引&#xff0c;第二个下标为该元素所在列的索引。如下图所示 行向量和列向量&#xff1a;只有单行的向量称为行向量&#xff0c;只有单列的称之为列向量。 相等 维数和元素都相等 数乘(与标量相乘) 每一个元素与…