JUC源码分析-线程池篇(三)ScheduledThreadPoolExecutor
JUC源码分析-线程池篇(三)ScheduledThreadPoolExecutor
ScheduledThreadPoolExecutor 继承自 ThreadPoolExecutor。它主要用来在给定的延迟之后运行任务,或者定期执行任务。ScheduledThreadPoolExecutor 的功能与 Timer 类似,但 Timer 对应的是单个后台线程,而 ScheduledThreadPoolExecutor 可以在构造函数中指定多个对应的后台线程数。
1. ScheduledThreadPoolExecutor 简介
1.1 Timer 和 ScheduledThreadPoolExecutor 区别
| Timer | ScheduledThreadPoolExecutor |
|---|---|
| 单线程 | 多线程 |
| 单个任务执行时间影响其他任务调度 | 多线程,不会影响 |
| 基于绝对时间 | 基于相对时间 |
| 一旦执行任务出现异常不会捕获,其他任务得不到执行 | 多线程,单个任务的执行不会影响其他线程 |
1.2 ScheduledThreadPoolExecutor 执行流程
ScheduledThreadPoolExecutor 的结构和 Timer 类似,也是由 DelayedWorkQueue、ThreadPoolExecutor、ScheduledFutureTask 三部分组成。DelayedWorkQueue 是一个无界队列,所以 ThreadPoolExecutor 的 maximumPoolSize 在 ScheduledThreadPoolExecutor 中没有什么意义(设置 maximumPoolSize 的大小没有什么效果)。
ScheduledThreadPoolExecutor 的执行主要分为两大部分。
1)当调用 ScheduledThreadPoolExecutor#scheduleAtFixedRate() 方法或者 scheduleWithFixedDelay() 方法时,会向 ScheduledThreadPoolExecutor#DelayedWorkQueue 添加一个实现了 RunnableScheduledFutur 接口的 ScheduledFutureTask。
2)线程池中的线程从 DelayedWorkQueue 中获取 ScheduledFutureTask,然后执行任务。

2. ScheduledThreadPoolExecutor 源码分析
2.1 数据结构

2.2 定时任务调度 schedule
schedule、scheduleAtFixedRate、scheduleWithFixedDelay 只是将任务设置执行时间后添加到线程池队列中去了。
ublic ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
long initialDelay, long period, TimeUnit unit) {
if (command == null || unit == null)
throw new NullPointerException();
if (period <= 0)
throw new IllegalArgumentException();
ScheduledFutureTask<Void> sft =
new ScheduledFutureTask<Void>(command, null,
triggerTime(initialDelay, unit), unit.toNanos(period));
RunnableScheduledFuture<Void> t = decorateTask(command, sft);
sft.outerTask = t;
delayedExecute(t);
return t;
}
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
long initialDelay, long delay, TimeUnit unit) {
if (command == null || unit == null)
throw new NullPointerException();
if (delay <= 0)
throw new IllegalArgumentException();
ScheduledFutureTask<Void> sft =
new ScheduledFutureTask<Void>(command, null,
triggerTime(initialDelay, unit), unit.toNanos(-delay));
RunnableScheduledFuture<Void> t = decorateTask(command, sft);
sft.outerTask = t;
delayedExecute(t);
return t;
}
2.3 任务执行 ScheduledFutureTask#run
public void run() {
boolean periodic = isPeriodic();
if (!canRunInCurrentRunState(periodic)) // 线程池关闭时是否断续执行定时任务
cancel(false);
else if (!periodic) // 只执行一次
ScheduledFutureTask.super.run();
else if (ScheduledFutureTask.super.runAndReset()) { // 周期性执行
setNextRunTime(); // 下一次执行时间
reExecutePeriodic(outerTask); // 重新添加到任务队列中
}
}
参考:
- 《深入理解Java线程池:ScheduledThreadPoolExecutor》:https://www.jianshu.com/p/925dba9f5969
每天用心记录一点点。内容也许不重要,但习惯很重要!
JUC源码分析-线程池篇(三)ScheduledThreadPoolExecutor的更多相关文章
- JUC源码分析-线程池篇(三)Timer
JUC源码分析-线程池篇(三)Timer Timer 是 java.util 包提供的一个定时任务调度器,在主线程之外起一个单独的线程执行指定的计划任务,可以指定执行一次或者反复执行多次. 1. Ti ...
- JUC源码分析-线程池篇(一):ThreadPoolExecutor
JUC源码分析-线程池篇(一):ThreadPoolExecutor Java 中的线程池是运用场景最多的并发框架,几乎所有需要异步或并发执行任务的程序都可以使用线程池.在开发过程中,合理地使用线程池 ...
- JUC源码分析-线程池篇(二)FutureTask
JUC源码分析-线程池篇(二)FutureTask JDK5 之后提供了 Callable 和 Future 接口,通过它们就可以在任务执行完毕之后得到任务的执行结果.本文从源代码角度分析下具体的实现 ...
- Elasticsearch源码分析—线程池(十一) ——就是从队列里处理请求
Elasticsearch源码分析—线程池(十一) 转自:https://www.felayman.com/articles/2017/11/10/1510291570687.html 线程池 每个节 ...
- 鸿蒙内核源码分析(线程概念篇) | 是谁在不停的折腾CPU? | 百篇博客分析OpenHarmony源码 | v21.06
百篇博客系列篇.本篇为: v21.xx 鸿蒙内核源码分析(线程概念篇) | 是谁在不断的折腾CPU | 51.c.h .o 任务管理相关篇为: v03.xx 鸿蒙内核源码分析(时钟任务篇) | 触发调 ...
- nginx源码分析线程池详解
nginx源码分析线程池详解 一.前言 nginx是采用多进程模型,master和worker之间主要通过pipe管道的方式进行通信,多进程的优势就在于各个进程互不影响.但是经常会有人问道,n ...
- nginx源码分析——线程池
源码: nginx 1.13.0-release 一.前言 nginx是采用多进程模型,master和worker之间主要通过pipe管道的方式进行通信,多进程的优势就在于各个进程互不影 ...
- 鸿蒙内核源码分析(调度机制篇) | 任务是如何被调度执行的 | 百篇博客分析OpenHarmony源码 | v7.07
百篇博客系列篇.本篇为: v07.xx 鸿蒙内核源码分析(调度机制篇) | 任务是如何被调度执行的 | 51.c.h .o 任务管理相关篇为: v03.xx 鸿蒙内核源码分析(时钟任务篇) | 触发调 ...
- 鸿蒙内核源码分析(时钟任务篇) | 触发调度谁的贡献最大 | 百篇博客分析OpenHarmony源码 | v3.05
百篇博客系列篇.本篇为: v03.xx 鸿蒙内核源码分析(时钟任务篇) | 触发调度谁的贡献最大 | 51.c.h .o 任务管理相关篇为: v03.xx 鸿蒙内核源码分析(时钟任务篇) | 触发调度 ...
随机推荐
- float不完整带来的IE7下的不兼容
这种原因是因为搜索用了float:right;添加报考院校和导入文件没有用float; 解决的方法是:1.给添加报考院校和导入文件分别添加float:left;2.把搜索那部分代码写在添加报考院校和导 ...
- 用Processing生成屏保(二)
代码 1: class TPoint 2: { 3: public TPoint(int _x, int _y) { 4: super(); 5: this._x = _x; 6: this._y = ...
- upc组队赛6 Progressive Scramble【模拟】
Progressive Scramble 题目描述 You are a member of a naive spy agency. For secure communication,members o ...
- CSS Sprites技术原理和使用
在分析各个网站的CSS时,我们经常可以看到一些网站有很多的元素共享了一张背景图片,而这张背景图片包含了所有这些元素需要的背景,这种技术就叫做CSS Sprites. 淘宝的css sprites ...
- php的闭包函数use的使用
PHP在默认情况下,匿名函数不能调用所在代码块的上下文变量,而需要通过使用use关键字. function getMoney() { $rmb = 1; $dollar = 6; $fun ...
- mysql全局权限账户%登录不上ERROR 1045 (28000): Access denied for user 'zzq'@'localhost' (using password: YES)
mysql中有新建了一个%(允许所有主机连接)和ALL权限的账户.但是竟然连不上.用root或者其他localhost的用户却可以登录.首先检查下防火墙打开了没,可以用service iptables ...
- python面试题之如何用Python找出你目前在哪个目录?
>>> import os >>> os.getcwd() 'C:\Users\lifei\AppData\Local\Programs\Python\Python ...
- Machine code transfer into assembly code
#include <stdio.h> const char shell[]="\x0f\x01\xf8\xe8\5\0\0\0\x0f\x01\xf8\x48\xcf" ...
- 导出数据库数据到Excel表
后台需要将用户信息数据导入到Excel表中提供给相关人员: 首先查询数据就不多说了: 导入Excel表直接亮代码(采用的是jxl的jar包提供的方法): public static File Impo ...
- CSUST 集训队选拔赛题解
选拔赛的题解,~~~ 题目链接:请点击 A题 素数筛 + 线段树(树状数组) 先用素数筛打表,然后线段树更新,遍历求出值,O(1)查询即可 AC代码: /*num数组 是把记录 数是否存在 存在即为1 ...