并发编程从零开始(十四)-Executors工具类

12 Executors工具类

concurrent包提供了Executors工具类,利用它可以创建各种不同类型的线程池

12.1 四种对比

单线程的线程池:

固定数目线程的线程池:

每接收一个请求,就创建一个线程来执行:

单线程具有周期调度功能的线程池:

多线程,有调度功能的线程池:


12.2 最佳实践

不同类型的线程池,其实都是由前面的几个关键配置参数配置而成的。

在《阿里巴巴Java开发手册》中,明确禁止使用Executors创建线程池,并要求开发者直接使用ThreadPoolExector或ScheduledThreadPoolExecutor进行创建。这样做是为了强制开发者明确线程池的运行策略,使其对线程池的每个配置参数皆做到心中有数,以规避因使用不当而造成资源耗尽的风险。


13 ScheduledThreadPoolExecutor

ScheduledThreadPoolExecutor实现了按时间调度来执行任务:

1. 延迟执行任务

2. 周期执行任务

区别如下:

AtFixedRate:按固定频率执行,与任务本身执行时间无关。但有个前提条件,任务执行时间必须小于间隔时间,例如间隔时间是5s,每5s执行一次任务,任务的执行时间必须小于5s。

WithFixedDelay:按固定间隔执行,与任务本身执行时间有关。例如,任务本身执行时间是10s,间隔2s,则下一次开始执行的时间就是12s。


13.1 延迟执行和周期性执行的原理

ScheduledThreadPoolExecutor继承了ThreadPoolExecutor,这意味着其内部的数据结构和ThreadPoolExecutor是基本一样的,那它是如何实现延迟执行任务和周期性执行任务的呢?

延迟执行任务依靠的是DelayQueue。DelayQueue是 BlockingQueue的一种,其实现原理是二叉堆。

而周期性执行任务是执行完一个任务之后,再把该任务扔回到任务队列中,如此就可以对一个任务反复执行。

不过这里并没有使用DelayQueue,而是在ScheduledThreadPoolExecutor内部又实现了一个特定的DelayQueue

其原理和DelayQueue一样,但针对任务的取消进行了优化。下面主要讲延迟执行和周期性执行的实现过程。


13.2 延迟执行

传进去的是一个Runnable,外加延迟时间delay。在内部通过decorateTask(...)方法把Runnable包装成一个ScheduleFutureTask对象,而DelayedWorkQueue中存放的正是这种类型的对象,这种类型的对象一定实现了Delayed接口。

从上面的代码中可以看出,schedule()方法本身很简单,就是把提交的Runnable任务加上delay时间,转换成ScheduledFutureTask对象,放入DelayedWorkerQueue中。任务的执行过程还是复用的ThreadPoolExecutor,延迟的控制是在DelayedWorkerQueue内部完成的。


13.4 执行周期

和schedule(...)方法的框架基本一样,也是包装一个ScheduledFutureTask对象,只是在延迟时间参数之外多了一个周期参数,然后放入DelayedWorkerQueue就结束了。

两个方法的区别在于一个传入的周期是一个负数,另一个传入的周期是一个正数,为什么要这样做呢?

用于生成任务序列号的sequencer,创建ScheduledFutureTask的时候使用:

withFixedDelay和atFixedRate的区别就体现在setNextRunTime里面。

如果是atFixedRate,period>0,下一次开始执行时间等于上一次开始执行时间+period;

如果是withFixedDelay,period < 0,下一次开始执行时间等于triggerTime(-p),为now+(-period),now即上一次执行的结束时间。

并发编程从零开始(十四)-Executors工具类的更多相关文章

  1. 并发编程(二)concurrent 工具类

    并发编程(二)concurrent 工具类 一.CountDownLatch 经常用于监听某些初始化操作,等初始化执行完毕后,通知主线程继续工作. import java.util.concurren ...

  2. 并发编程从零开始(十一)-Atomic类

    并发编程从零开始(十一)-Atomic类 7 Atomic类 7.1 AtomicInteger和AtomicLong 如下面代码所示,对于一个整数的加减操作,要保证线程安全,需要加锁,也就是加syn ...

  3. Java从零开始学二十四(集合工具类Collections)

    一.Collections简介 在集合的应用开发中,集合的若干接口和若干个子类是最最常使用的,但是在JDK中提供了一种集合操作的工具类 —— Collections,可以直接通过此类方便的操作集合 二 ...

  4. ~~并发编程(十四):Queue~~

    进击のpython ***** 并发编程--Queue 进程其实就提过这个Queue的问题,我们为什么在进程使用Queue? 是因为当时我们想要对共享数据进行修改,同时也希望它能够自动的给我加个锁 基 ...

  5. Java笔记(二十四)……集合工具类Collections&Arrays

    Collections 集合框架的工具类,方法全部为静态 Collections与Collection的区别 Collection是集合框架的一个顶层接口,里面定义了单列集合的共性方法 Collect ...

  6. Java并发编程(十四)-- 线程池实现原理

    在上一章我们从宏观上介绍了ThreadPoolExecutor,本文将深入解析一下线程池的具体实现原理 原理解析 线程池状态 在ThreadPoolExecutor中定义了一个volatile变量,另 ...

  7. Java并发编程(十四)Java内存模型

    1.共享内存和消息传递 线程之间的通信机制有两种:共享内存和消息传递:在共享内存的并发模型里,线程之间共享程序的公共状态,线程之间通过写-读内存中的公共状态来隐式进行通信.在消息传递的并发模型里,线程 ...

  8. 并发编程(十四)—— ScheduledThreadPoolExecutor 实现原理与源码深度解析 之 DelayedWorkQueue

    我们知道线程池运行时,会不断从任务队列中获取任务,然后执行任务.如果我们想实现延时或者定时执行任务,重要一点就是任务队列会根据任务延时时间的不同进行排序,延时时间越短地就排在队列的前面,先被获取执行. ...

  9. C#高级编程五十四天----Lookup类和有序字典

    Lookup类 Dictionary<Tkey,TValue>仅仅为每一个键支持一个值.新类Lookup<Tkey,TValue>是.NET3.5中新增的,它类似与Dictio ...

  10. java并发编程(十四)----(JUC原子类)对象的属性修改类型介绍

    今天我们介绍原子类的最后一个类型--对象的属性修改类型: AtomicIntegerFieldUpdater,AtomicLongFieldUpdater,AtomicReferenceFieldUp ...

随机推荐

  1. PHP方法参数的那点事儿

    在所有的编程语言中,方法或者函数,都可以传递一些参数进来进行业务逻辑的处理或者计算.这没什么可说的,但是在PHP中,方法的参数还有许多非常有意思的能力,下面我们就来说说这方面的内容. 引用参数 涉及到 ...

  2. mybatis关系表

    <select id="selectSingleQuestion" resultType="remarkPaper"> select FrontTi ...

  3. span标签的巧用

    前言: 用struts的标签结合<td>标签将后台数据在表格里渲染了出来,目前需求是需要将两个状态组合在一起显示 解决:通过span标签在td里的套用可以实现 <logic:notE ...

  4. Spring,IOC源码分析

    有错勿喷 1.首先是Spring,IOC的基本概念 IOC是一个容器 容器启动的时候创建所有单实例对象 我们可以直接从容器中获取到这个对象 2.调试流程 ioc容器的启动过程?启动期间都做了什么(什么 ...

  5. kendoUI 多选下拉列表 kendoMultiSelect

    问题1:被重复渲染 点击新增按钮----弹出模态框 多选下拉列表在多选框中只是初始化过一次.但是每次点击新增后  发现 多选下拉列表 被重复渲染了 解决方案 在 新增时  先将其父元素div中  的s ...

  6. 前端VUE基于gitlab的CI_CD

    目录 CI 1.Gitlab的CI 1.1 GitLab-Runner 1.2 .gitlab-ci.yml 1.3 配置.gitlab-ci.yml 1.3.1 Pipeline概念 1.3.2 S ...

  7. 2019 年 CNCF 中国云原生调查报告

    中国 72% 的受访者生产中使用 Kubernetes 在 CNCF,为更好地了解开源和云原生技术的使用,我们定期调查社区.这是第三次中国云原生调查,以中文进行,以便更深入地了解中国云原生技术采用的步 ...

  8. 干货分享之Spring框架源码解析01-(xml配置解析)

    记录并分享一下本人学习spring源码的过程,有什么问题或者补充会持续更新.欢迎大家指正! 环境: spring5.X + idea Spring 是一个工厂,是一个负责对象的创建和维护的工厂.它给我 ...

  9. Data Management Tools(数据管理工具)《一》

    数据管理工具 1.LAS数据集 # Process: LAS 数据集统计数据 arcpy.LasDatasetStatistics_management("", "SKI ...

  10. 题解 Wide Swap

    题目传送门 题目大意 给出一个长度为 \(n\) 的排列 \(a_{1,2,...,n}\) 以及常数 \(k\),每次可以交换两个数 \(a_i,a_j\) 当且仅当 \(j-i\ge k \tex ...