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. docker volume持久化存储与数据分享

    第一种 指定volume文件mysql存储,存储的位置为/var/lib/mysql -v mysql:/var/lib/mysql 第二种 同步文件,将容器中的skeleton文件夹的内容同步到宿主 ...

  2. 更换nginx默认端口以及配置文件位置

    前言 近段时间在准备毕业设计的前期准备,基本确定了前后端分离的架构,于是就需要用到了nginx. 在之前nginx是放在docker上,所以没有端口更改跟配置文件配置的烦恼.但是现在是直接放在服务器上 ...

  3. 手动安装easy-install/pip

    1.wget --no-check-certificate https://bootstrap.pypa.io/ez_setup.py 2.在root用户下 python ez_setup.py -- ...

  4. python基础【第九篇】

    补充知识 1.字符串方法的补充 s = str() s.format() # 格式化输出 "连接符".join("连接的对象") # 拼接 s.find() # ...

  5. Java-技术专区-技术栈分析辨证方法

    1.好多公司动不动就JVM.高并发.分布式.微服务等等,我没有实际经验. 2.从事Java开发三年了,目前的职位是高级Java工程师,感觉技术和工资都到了瓶颈,对以后的发展方向有些迷茫. 3.加班时间 ...

  6. Java-技术专区-虚拟机系列-内存模型(JMM)

           Java8内存模型—永久代(PermGen)和元空间(Metaspace) 一.JVM 内存模型 根据 JVM 规范,JVM 内存共分为虚拟机栈.堆.方法区.程序计数器.本地方法栈五个部 ...

  7. 利用ARIMA算法建立短期预测模型

    周五福利日活动是电信为回馈老用户而做的活动,其主要回馈老用户的方式是让用户免费领取对应的优惠券,意在提升老用户的忠诚度和活跃度.今日,为保证仓库备货优惠券资源充足,特别是5元话费券等,需要对该类优惠券 ...

  8. AtCoder ABC 131F Must Be Rectangular!

    题目链接:https://atcoder.jp/contests/abc131/tasks/abc131_f 转自博客:https://blog.csdn.net/qq_37656398/articl ...

  9. 在三台服务器,搭建redis三主三从集群

    一.资源准备 1.准备三台服务器H1.H2.H3 172.26.237.83 H1 172.26.237.84 H2 172.26.237.85 H3 二.配置服务器 1.在H1服务器设置SSH免密登 ...

  10. linux,进行批量下载文件操作

     wget -i url.txt -P ./Photo 批量下载图片(一般是某个相册的图片) 首先先得到一张图片的地址如:www.example.com/pic/001.jpg 同相册的图片地址会有一 ...