JUC源码分析-线程池篇(三)ScheduledThreadPoolExecutor

ScheduledThreadPoolExecutor 继承自 ThreadPoolExecutor。它主要用来在给定的延迟之后运行任务,或者定期执行任务。ScheduledThreadPoolExecutor 的功能与 Timer 类似,但 Timer 对应的是单个后台线程,而 ScheduledThreadPoolExecutor 可以在构造函数中指定多个对应的后台线程数。

  1. JUC源码分析-线程池篇(三)Timer

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); // 重新添加到任务队列中
}
}

参考:

  1. 《深入理解Java线程池:ScheduledThreadPoolExecutor》:https://www.jianshu.com/p/925dba9f5969

每天用心记录一点点。内容也许不重要,但习惯很重要!

JUC源码分析-线程池篇(三)ScheduledThreadPoolExecutor的更多相关文章

  1. JUC源码分析-线程池篇(三)Timer

    JUC源码分析-线程池篇(三)Timer Timer 是 java.util 包提供的一个定时任务调度器,在主线程之外起一个单独的线程执行指定的计划任务,可以指定执行一次或者反复执行多次. 1. Ti ...

  2. JUC源码分析-线程池篇(一):ThreadPoolExecutor

    JUC源码分析-线程池篇(一):ThreadPoolExecutor Java 中的线程池是运用场景最多的并发框架,几乎所有需要异步或并发执行任务的程序都可以使用线程池.在开发过程中,合理地使用线程池 ...

  3. JUC源码分析-线程池篇(二)FutureTask

    JUC源码分析-线程池篇(二)FutureTask JDK5 之后提供了 Callable 和 Future 接口,通过它们就可以在任务执行完毕之后得到任务的执行结果.本文从源代码角度分析下具体的实现 ...

  4. Elasticsearch源码分析—线程池(十一) ——就是从队列里处理请求

    Elasticsearch源码分析—线程池(十一) 转自:https://www.felayman.com/articles/2017/11/10/1510291570687.html 线程池 每个节 ...

  5. 鸿蒙内核源码分析(线程概念篇) | 是谁在不停的折腾CPU? | 百篇博客分析OpenHarmony源码 | v21.06

    百篇博客系列篇.本篇为: v21.xx 鸿蒙内核源码分析(线程概念篇) | 是谁在不断的折腾CPU | 51.c.h .o 任务管理相关篇为: v03.xx 鸿蒙内核源码分析(时钟任务篇) | 触发调 ...

  6. nginx源码分析线程池详解

    nginx源码分析线程池详解 一.前言     nginx是采用多进程模型,master和worker之间主要通过pipe管道的方式进行通信,多进程的优势就在于各个进程互不影响.但是经常会有人问道,n ...

  7. nginx源码分析——线程池

    源码: nginx 1.13.0-release   一.前言      nginx是采用多进程模型,master和worker之间主要通过pipe管道的方式进行通信,多进程的优势就在于各个进程互不影 ...

  8. 鸿蒙内核源码分析(调度机制篇) | 任务是如何被调度执行的 | 百篇博客分析OpenHarmony源码 | v7.07

    百篇博客系列篇.本篇为: v07.xx 鸿蒙内核源码分析(调度机制篇) | 任务是如何被调度执行的 | 51.c.h .o 任务管理相关篇为: v03.xx 鸿蒙内核源码分析(时钟任务篇) | 触发调 ...

  9. 鸿蒙内核源码分析(时钟任务篇) | 触发调度谁的贡献最大 | 百篇博客分析OpenHarmony源码 | v3.05

    百篇博客系列篇.本篇为: v03.xx 鸿蒙内核源码分析(时钟任务篇) | 触发调度谁的贡献最大 | 51.c.h .o 任务管理相关篇为: v03.xx 鸿蒙内核源码分析(时钟任务篇) | 触发调度 ...

随机推荐

  1. Excel2016怎么批量删除空白行 如何删除空白行

    我们在编辑Excel文档的时候,如果表格中有大量的空白行,这时我们怎么样把它们批量删除呢?下面我们就一起来看看操作的方法吧.   工具/原料   Excel2016 方法/步骤     首先在电脑上打 ...

  2. 查看.Net Framework的版本(PC和WinCE)

    一.在电脑上查看.Net Framework的版本 (1)第一步: 打开“我的电脑“,在地址栏输入 %systemroot%\Microsoft.NET\Framework 第二步:从列出来的文件夹中 ...

  3. JPA单向和双向关系

    单向关系 @JoinColumn 双向关系 @OneToMany @ManyToMany mappedBy

  4. 关于原生js中ie的attacheEvent事件用匿名函数改变this指向后,不能用detachEvent删除绑定事件的解决办法?

    博客搬迁,给你带来的不便,敬请谅解! http://www.suanliutudousi.com/2017/11/28/%e5%85%b3%e4%ba%8e%e5%8e%9f%e7%94%9fjs%e ...

  5. gdb调试已在运行中的进程

    一.在服务器上调试进程,服务器上并没有源代码,所以需要将源码上传至服务器,才能调试看到源码,以下是步骤: 1.查看服务进程id:pgrep 服务名 [user@user-MP app]$ pgrep ...

  6. zabbix添加对web页面url的状态监控

    zabbix3.0.4添加对web页面url的状态监控 1.应用集配置 在配置—>主机中打开主机列表,选择需要添加监控主机的web,创建应用集 2.web监测配置 选择web场景,再单击右上角的 ...

  7. linux 之文件重命名

    没有专门的重命名 命令 用 mv a b 就可以重命名了 mv :move 移动文件(延伸功能:重命名,linux系统没有专门的重命名命令) 基本格式: 移动文件:mv 文件名 移动目的地文件名 重命 ...

  8. fragment中的onCreateView和onViewCreated的区别和

    (1)  onViewCreated在onCreateView执行完后立即执行. (2)  onCreateView返回的就是fragment要显示的view.

  9. texinfo - 软件文档系统

    DESCRIPTION 描述 Texinfo 是一种文档系统,使用单一的源文件来产生在线文档以及可打印的输出.它主要用于书写软件使用手册. 要查看 Texinfo 语言和相关工具的全面描述,请查看 T ...

  10. 项目案例之Pipeline流水线发布JAVA项目(三)

    项目案例之Pipeline流水线发布JAVA项目(三) 链接:https://pan.baidu.com/s/1NZZbocZuNwtQS0eGkkglXQ 提取码:z7gj 复制这段内容后打开百度网 ...