ThreadPoolExecutor组成

ThreadPoolExecutor的核心构造函数:

public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}

根据构造方法可以看才ThreadPoolExecutor主要分为以下几个部分:

  1. corePoolSize:核心线程池能容纳的线程数
  2. maximumPoolSize:线程池最大能容纳的线程数(实际是当核心线程池满了之后会进行扩容maxSize - coreSize)
  3. keepAliveTime: 当线程执行完毕之后等待被销毁的时间
  4. workQueue:存放等待执行的任务,是一个BlockingQueue。
  5. ThreadFactory: 线程的构造方法
  6. RejectedExecutionHandler: 线程被拒绝加入线程池时执行的策略

等待队列 BlockingQueue

  • ArrayBlockingQueue : 基于数组的先进先出队列,构造时必须指明大小;
  • LinkedBlockingDeque : 基于链表的队列,如果构造时没有指明大小,则默认为Integer.MAX_VALUE;
  • SynchronousQueue : 一次只会执行一个Thread的队列。

线程池新入线程

线程池的策略,当来新线程时:

  1. 如果线程池中有空闲线程,就复用空闲线程。
  2. 如果没有空闲线程,就将新线程加入等待队列。
  3. 如果来的线程太多,等待队列也满了,就临时扩容到maxPoolSize,相当于使用了一个临时线程池来使用。
  4. 如果扩容还是无法满足,就执行拒绝策略。具体的拒绝策略根据创建时的handler决定。
  5. 线程池通过使用一个Woker负责循环从等待队列中获取线程执行。

ThreadPoolExecutor用法

1. 直接实例化一个

public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), handler);
}

2. 使用Executorsnew****Pool()方法创建ExecutorService:

每一个new****Pool方法实质也是调用ThreadPoolExecutor的构造方法,只是传入的参数是设定好的。

public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
  • FixedThreadPool : 核心线程池大小和最大线程池一样,缓存队列为LinkedBlokingQueue,超出线程池满了之后进入的线程都会被加入等待队列。
  • ScheduledThreadPool : 核心线程池大小用户决定,最大线程池大小为Integer.MAX_VALUE。等待队列为:DelayedWorkQueue
  • SingleThreadExecutor : 核心线程池为0,意味着新的线程马上就会被创建。

ThreadPoolExecutor和ExecutorService的区别

首先ExecutorExecutorService都是接口,ThreadPoolExecutor是类。

通过Executors.new****Pool创建线程池返回的都是ExecutorService的实例,相当于是调用的ThreadPoolExecutor的构造方法,返回的是它的父类AbstracExecutorService的实例。AbstracExecutorService又是实现了ExecutorService接口的抽象类。

ThreadPoolExecutor理解的更多相关文章

  1. java线程池ThreadPoolExecutor理解

    Java通过Executors提供四种线程池,分别为:newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程.newFixe ...

  2. 009-ThreadPoolExecutor运转机制详解,线程池使用1-newFixedThreadPool、newCachedThreadPool、newSingleThreadExecutor、newScheduledThreadPool

    一.ThreadPoolExecutor理解 为什么要用线程池: 1.减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务. 2.可以根据系统的承受能力,调整线程池中工作线线程的数 ...

  3. android线程池ThreadPoolExecutor的理解

    android线程池ThreadPoolExecutor的理解 线程池 我自己理解看来.线程池顾名思义就是一个容器的意思,容纳的就是ThreadorRunable, 注意:每一个线程都是需要CPU分配 ...

  4. ThreadPoolExecutor的一点理解

    整个ThreadPoolExecutor的任务处理有4步操作: 第一步,初始的poolSize < corePoolSize,提交的runnable任务,会直接做为new一个Thread的参数, ...

  5. Java 并发系列(一) ThreadPoolExecutor源码解析及理解

    ThreadPoolExecutor 它是线程池最核心的类, 这里对核心的方法做简要的剖析(会持续更新),以加深对线程池运行原理的理解. 1. 核心成员变量及相关方法 // ctl非常重要,用整型表示 ...

  6. 深入理解java线程池—ThreadPoolExecutor

    几句闲扯:首先,我想说java的线程池真的是很绕,以前一直都感觉新建几个线程一直不退出到底是怎么实现的,也就有了后来学习ThreadPoolExecutor源码.学习源码的过程中,最恶心的其实就是几种 ...

  7. ThreadPoolExecutor的一点理解 专题

    corePoolSize(maxActiveThreadSize):线程池大小,决定着新提交的任务是新开线程云执行还是放到任务队列中,也是线程池的最最核心的参数.一般线程池开始时是没有线程的,只有当任 ...

  8. 多线程学习笔记-深入理解ThreadPoolExecutor

    java多线程中,线程池的最上层接口是Executor,ExecutorService实现了Executor,是真正的管理线程池的接口,ThreadPoolExecutor间接继承了ExecutorS ...

  9. 理解ThreadPoolExecutor线程池的corePoolSize、maximumPoolSize和poolSize

    我们知道,受限于硬件.内存和性能,我们不可能无限制的创建任意数量的线程,因为每一台机器允许的最大线程是一个有界值.也就是说ThreadPoolExecutor管理的线程数量是有界的.线程池就是用这些有 ...

随机推荐

  1. 踪电子表格中的单元格(Spreadsheet Tracking, ACM/ICPC World Finals 1997, UVa512)

    有一个r行c列(1≤r,c≤50)的电子表格,行从上到下编号为1-r,列从左到右编号为1 -c.如图4-2(a)所示,如果先删除第1.5行,然后删除第3, 6, 7, 9列,结果如图4-2(b) 所示 ...

  2. NOIP2018 滚粗记

    Day -2  上午,大家都在复习各种模板,zhx总结了足足67个模板(杨辉三角也算模板???),lgl死磕FFT发现cos和sin打反了,我也是复习板子和以前做过的题,几乎没有人颓. 接着jdr,l ...

  3. web前端学习总结--CSS

    CSS 什么是CSS? CSS 指层叠样式表(Cascading Style Sheets) 样式定义如何显示HTML元素 样式通常存储在样式表中 如何使用CSS 内联方式 样式定义在单个的HTML元 ...

  4. python 函数编写指南

    #函数编写指南:1.给函数指定描述性名称,且只在其中是用小写字母和下划线 2.每个函数都应包含简要的阐述其功能的注释,该注释应紧跟在函数定义后面,且采用文档字符串格式 3.给形参指定默认值时,等号两边 ...

  5. Flask - 路由系统

    目录 Flask - 路由系统 @app.route()装饰器中的常用参数 methods : 当前 url 地址,允许访问的请求方式 endpoint:反向url地址,默认为视图函数名(url_fo ...

  6. HTML5本地存储——Web SQL Database与indexedDB

    虽然在HTML5 WebStorage介绍了html5本地存储的Local Storage和Session Storage,这两个是以键值对存储的解决方案,存储少量数据结构很有用,但是对于大量结构化数 ...

  7. Java基础——基础数据类型与读入输出

    首先我们写完了HelloWorld就学会了java的一种输出 System.out.println() 用起来就像是被强化过的C++的puts函数 或者就是自带endl的cout函数,中间的" ...

  8. mybatis源码阅读-执行器StatementHandle和ParameterHandler(五)

    StatementHandle 类图 各个实现类的作用 SimpleStatementHandler 用于使用Statement操作数据库(不会使用参数化查询?) PreparedStatementH ...

  9. group by语句,聚合函数与其他语句(关系,执行过程)

    (本文一切基于SQL SERVER 2008 R2) 先来看一个语句执行过程发生的错误提示: 消息 8120,级别 16,状态 1,第 2 行 选择列表中的列 'SC.CNO' 无效,因为该列没有包含 ...

  10. springCloud学习-服务消费者(Feign)

    1.简介 Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单.使用Feign,只需要创建一个接口并注解.它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解.Fei ...