结构

类继承图:

上面的各个接口/类的关系和作用:

  1. Executor

    执行器接口,也是最顶层的抽象核心接口, 分离了任务和任务的执行。
  2. ExecutorService

    在Executor的基础上提供了执行器生命周期管理,任务异步执行等功能。
  3. ScheduledExecutorService

    在ExecutorService基础上提供了任务的延迟执行/周期执行的功能。
  4. Executors

    生产具体的执行器的静态工厂
  5. ThreadFactory

    线程工厂,用于创建单个线程,减少手工创建线程的繁琐工作,同时能够复用工厂的特性。
  6. AbstractExecutorService

    ExecutorService的抽象实现,为各类执行器类的实现提供基础。
  7. ThreadPoolExecutor

    线程池Executor,也是最常用的Executor,可以以线程池的方式管理线程。
  8. ScheduledThreadPoolExecutor

    在ThreadPoolExecutor基础上,增加了对周期任务调度的支持。
  9. ForkJoinPool

    Fork/Join线程池,在JDK1.7时引入,时实现Fork/Join框架的核心类。

ThreadPoolExecutor

线程工厂

ThreadPoolExecutor在构造时如果用户不指定ThreadFactory,则默认使用Executors.defaultThreadFactory()创建一个ThreadFactory,即Executors.DefaultThreadFactory:

public static ThreadFactory defaultThreadFactory() {
return new DefaultThreadFactory();
} /**
* 默认的线程工厂.
*/
static class DefaultThreadFactory implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix; DefaultThreadFactory() {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
namePrefix = "pool-" + poolNumber.getAndIncrement() + "-thread-";
} public Thread newThread(Runnable r) {
Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);
if (t.isDaemon())
t.setDaemon(false);
if (t.getPriority() != Thread.NORM_PRIORITY)
t.setPriority(Thread.NORM_PRIORITY);
return t;
}
}

线程池中任务线程Worker

private final class Worker
extends AbstractQueuedSynchronizer
implements Runnable
{
private static final long serialVersionUID = 6138294804551838833L;
// 这个是真正的线程,任务靠你啦
final Thread thread;
// 前面说了,这里的 Runnable 是任务。为什么叫 firstTask?因为在创建线程的时候,如果同时指定了
// 这个线程起来以后需要执行的第一个任务,那么第一个任务就是存放在这里的(线程可不止执行这一个任务)
// 当然了,也可以为 null,这样线程起来了,自己到任务队列(BlockingQueue)中取任务(getTask 方法)就行了
Runnable firstTask;
// 用于存放此线程完成的任务数,注意了,这里用了 volatile,保证可见性
volatile long completedTasks;
// Worker 只有这一个构造方法,传入 firstTask,也可以传 null
Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
// 调用 ThreadFactory 来创建一个新的线程
this.thread = getThreadFactory().newThread(this);
}
// 这里调用了外部类的 runWorker 方法
public void run() {
runWorker(this);
}
...// 其他几个方法没什么好看的,就是用 AQS 操作,来获取这个线程的执行权,用了独占锁
}

特别要注意这里的初始化,将this 任务分配给了线程thread ,后面调用线程start,即调用Worker中的run`方法。

注意点

看源码要注意两个对象

一个是任务队列BlockingQueue<Runnable> workQueue

一个是任务线程集合HashSet<Worker> workers

线程池进度流程

  • 工作线程数小于等于corePoolSize,这里将任务firstTask包装成worker,并新增到worker

  • 工作线程数大于corePoolSize且可以入队,这里将任务command入队到workQueue

    • 这里有一个特殊点addWorker(null, false),这里是为了防止任务入队了,但是工作线程为0,这里就是为了新增一个工作线程,即再新增一个firstTasknullworkerworkers中。
  • workQueue队列已满,小于maximumPoolSize,再次将任务firstTask包装成worker,并新增到workers中。

上述的firstTask包装成worker,当worker中的线程启动时,会自旋不停的处理任务,第一个处理的就是worker中的firstTask,如果firstTask处理结束或firstTasknull,那么继续调用getTask方法从队列workQueue中获取任务处理。

参考:

Java多线程进阶(三九)—— J.U.C之executors框架:executors框架概述

深度解读 java 线程池设计思想及源码实现

JAVA并发-Executor的更多相关文章

  1. java并发编程-Executor框架

    Executor框架是指java 5中引入的一系列并发库中与executor相关的一些功能类,其中包括线程池,Executor,Executors,ExecutorService,Completion ...

  2. [转]Java并发的四种风味:Thread、Executor、ForkJoin和Actor

    这篇文章讨论了Java应用中并行处理的多种方法.从自己管理Java线程,到各种更好几的解决方法,Executor服务.ForkJoin 框架以及计算中的Actor模型. Java并发编程的4种风格:T ...

  3. Java 并发编程——Executor框架和线程池原理

    Eexecutor作为灵活且强大的异步执行框架,其支持多种不同类型的任务执行策略,提供了一种标准的方法将任务的提交过程和执行过程解耦开发,基于生产者-消费者模式,其提交任务的线程相当于生产者,执行任务 ...

  4. 那些年读过的书《Java并发编程实战》和《Java并发编程的艺术》三、任务执行框架—Executor框架小结

    <Java并发编程实战>和<Java并发编程的艺术>           Executor框架小结 1.在线程中如何执行任务 (1)任务执行目标: 在正常负载情况下,服务器应用 ...

  5. (转)java并发编程--Executor框架

    本文转自https://www.cnblogs.com/MOBIN/p/5436482.html java并发编程--Executor框架 只要用到线程,就可以使用executor.,在开发中如果需要 ...

  6. java并发编程 Executor,Executors,ExecutorService,CompletionService,Future,C

    使用CompletionService获取多线程返回值 CompletionService和ExecutorCompletionService详解 Java并发编程系列之十五:Executor框架

  7. Java 并发编程——Executor框架和线程池原理

    Java 并发编程系列文章 Java 并发基础——线程安全性 Java 并发编程——Callable+Future+FutureTask java 并发编程——Thread 源码重新学习 java并发 ...

  8. 【Java 并发】Executor框架机制与线程池配置使用

    [Java 并发]Executor框架机制与线程池配置使用 一,Executor框架Executor框架便是Java 5中引入的,其内部使用了线程池机制,在java.util.cocurrent 包下 ...

  9. Java并发学习 & Executor学习 & 异常逃逸 & 同步互斥Best Practice & wait/notify, conditon#await/signal

    看了这篇文章:http://www.ciaoshen.com/2016/10/28/tij4-21/ 有一些Java并发的内容,另外查了一些资料. 朴素的Thread 首先,Java中关于线程Thre ...

随机推荐

  1. http与Rpc

    RPC即远程服务调用 出现原因:随着项目越来越大,访问量越来越大,为了突破性能瓶颈,需要将项目拆分成多个部分,这样比起传统的项目都是本地内存调用,分布式的项目之间需要在网络间进行通信 服务之间的远程调 ...

  2. django自定义错误处理

    要实现自定义错误处理的功能,总共分4步: 1.创建html错误页 2.配置settings ,当DEBUG=True,则不会生效 3.编写视图 4.配置url views.py   def page_ ...

  3. 补充: Nginx

    1. 定义: Nginx ("engine x") 是一个高性能的HTTP和反向代理服务器: 特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现 ...

  4. 六、Spring之初步认识AOP

    Spring之初步认识AOP [1]AOP概览 什么是AOP?(来自百度) ​ 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行 ...

  5. 本地运行vue项目webpack提示 Compiled successfully

    最近在github下载运行别人的vue项目后,如下图提示编译成功,但项目并没有启动       最开始我以为是端口问题,修改了config-index.js里的port端口,重新运行后依然是上图提示 ...

  6. sql server中的临时表、表变量和公用表表达式

    在编写T-SQL语句的时候,SQL Server提供了三种方法临时存储某些结果集,分别是临时表.表变量和公用表表达式. 临时表 临时表需要在临时数据库TempDB中通过I/O操作来创建表结构,一旦用户 ...

  7. Entity Framework 6 中如何获取 EntityTypeConfiguration 的 Edm 信息?(三)

    接着上一篇,我们继续来优化. 直接贴代码了: LambdaHelper.cs using System; using System.Collections.Generic; using System. ...

  8. Kafka 2.3 Producer (0.9以后版本适用)

    kafka0.9版本以后用java重新编写了producer,废除了原来scala编写的版本. 这里直接使用最新2.3版本,0.9以后的版本都适用. 注意引用的包为:org.apache.kafka. ...

  9. vue中使用的一些问题(IE不兼容,打包样式不生效)

    通过脚手架快速创建的项目,使用了swiper组件,项目中使用了es6语法,使用了babel-polyfill转化依旧不行,仔细排查项目中的使用组件,最后找到问题所在 swiper4.5.0版本太高,不 ...

  10. Window权限维持(二):计划任务

    Windows操作系统提供了一个实用程序(schtasks.exe),使系统管理员能够在特定的日期和时间执行程序或脚本.这种行为可作为一种持久性机制被red team利用.通过计划任务执行持久性不需要 ...