定时任务实现方式对比
2019-10-16 08:13:25来源:博客园 阅读 ()
定时任务实现方式对比
1. 定时任务实现方式对比
1.1. Timer
- 代码例子如下
public static void main(String[] args) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime localDateTime = LocalDateTime.now();
String format = localDateTime.format(formatter);
System.out.println("1:"+format);
Timer timer = new Timer();
for (int i = 0; i < 2; i++) {
timer.schedule(new TimerTask() {
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread name : "+ Thread.currentThread().getName());
LocalDateTime localDateTime = LocalDateTime.now();
String format = localDateTime.format(formatter);
System.out.println("2:"+format);
}
}, 3000);
}
localDateTime = LocalDateTime.now();
format = localDateTime.format(formatter);
System.out.println("3:"+format);
}
结果
1:2019-10-14 17:35:13
3:2019-10-14 17:35:13
Thread name : Timer-0
2:2019-10-14 17:35:19
Thread name : Timer-0
2:2019-10-14 17:35:22
- 可以看出同一个Timer的定时任务,后台就一个线程管理任务分配,遇到任务阻塞,可能导致下一个任务延迟
- 且如果任务发生异常,系统就终止了
1.2. ScheduledExecutorService
- 为了解决Timer的问题,
ScheduledExecutorService
做了改进,采用了线程池的定时任务队列,实际使用的也是最小堆排序 - 代码如下
private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
public static void main(String[] args) {
// timerTest();
print("1:");
ScheduledExecutorService service = new ScheduledThreadPoolExecutor(2);
for (int i = 0; i < 2; i++) {
service.schedule(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread name : " + Thread.currentThread().getName());
print("2:");
}
}, 3, TimeUnit.SECONDS);
}
print("3:");
service.shutdown();
}
private static void print(String s) {
LocalDateTime localDateTime = LocalDateTime.now();
String format = localDateTime.format(formatter);
System.out.println(s + format);
}
结果
1:2019-10-15 11:53:54
3:2019-10-15 11:53:54
Thread name : pool-1-thread-1
2:2019-10-15 11:54:00
Thread name : pool-1-thread-2
2:2019-10-15 11:54:00
明白它的延迟原理和Timer一样,可以知道如果我把核心线程数改成1,则效果和Timer类似
- 结果如下,两个任务延迟3秒,前一个任务会导致后一个任务延迟
1:2019-10-15 11:57:40
3:2019-10-15 11:57:40
Thread name : pool-1-thread-1
2:2019-10-15 11:57:46
Thread name : pool-1-thread-1
2:2019-10-15 11:57:49
- 它的优势在于可以多线程执行,一定程度上避免任务间互相影响,同时单个任务异常不影响其它任务
1.3. 时间轮(延迟消息)
- 本质是环形数组,比如上述8个节点的时间轮,每个节点存放任务队列,比如我们需要新建5s延迟的任务,就放5的节点,新建10s延迟的任务就放2的节点,设延迟时间为n,则节点位置为n%8,同时需记下轮询圈数n/8
- 优势:当任务数量非常多的时候采用这样环形数组加队列是个效率比较高的选择
- 想要了解更多时间轮实现,可以参考文章下的参考博客
1.4. 分布式定时任务
- github上也有些开源的分布式定时任务的方案,可以直接使用
- 如xxl_job,elastic-job-lite,light-task-scheduler,以哪个火用哪个的原则,那还是xxl_job的星星最多,另外两个已经两年没更新了
参考博客:
延迟消息之时间轮
原文链接:https://www.cnblogs.com/sky-chen/p/11678081.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:Java多线程编程
下一篇:成员变量的隐藏和方法重写
- DES/3DES/AES 三种对称加密算法实现 2020-06-11
- SpringBoot + Vue + ElementUI 实现后台管理系统模板 -- 后 2020-06-10
- Spring Boot 实现定时任务的 4 种方式 2020-06-10
- SpringBoot通过web页面动态控制定时任务的启动、停止、创建 2020-06-09
- JSP+SSH+Mysql+DBCP实现的租车系统 2020-06-09
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash