ThreadPoolExecutor理解
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主要分为以下几个部分:
- corePoolSize:核心线程池能容纳的线程数
- maximumPoolSize:线程池最大能容纳的线程数(实际是当核心线程池满了之后会进行扩容
maxSize - coreSize
) - keepAliveTime: 当线程执行完毕之后等待被销毁的时间
- workQueue:存放等待执行的任务,是一个BlockingQueue。
- ThreadFactory: 线程的构造方法
- RejectedExecutionHandler: 线程被拒绝加入线程池时执行的策略
等待队列 BlockingQueue
- ArrayBlockingQueue : 基于数组的先进先出队列,构造时必须指明大小;
- LinkedBlockingDeque : 基于链表的队列,如果构造时没有指明大小,则默认为
Integer.MAX_VALUE
; - SynchronousQueue : 一次只会执行一个Thread的队列。
线程池新入线程
线程池的策略,当来新线程时:
- 如果线程池中有空闲线程,就复用空闲线程。
- 如果没有空闲线程,就将新线程加入等待队列。
- 如果来的线程太多,等待队列也满了,就临时扩容到
maxPoolSize
,相当于使用了一个临时线程池来使用。 - 如果扩容还是无法满足,就执行拒绝策略。具体的拒绝策略根据创建时的handler决定。
- 线程池通过使用一个
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. 使用Executors
的new****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的区别
首先Executor
和ExecutorService
都是接口,ThreadPoolExecutor
是类。
通过Executors.new****Pool
创建线程池返回的都是ExecutorService
的实例,相当于是调用的ThreadPoolExecutor
的构造方法,返回的是它的父类AbstracExecutorService
的实例。AbstracExecutorService
又是实现了ExecutorService
接口的抽象类。
ThreadPoolExecutor理解的更多相关文章
- java线程池ThreadPoolExecutor理解
Java通过Executors提供四种线程池,分别为:newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程.newFixe ...
- 009-ThreadPoolExecutor运转机制详解,线程池使用1-newFixedThreadPool、newCachedThreadPool、newSingleThreadExecutor、newScheduledThreadPool
一.ThreadPoolExecutor理解 为什么要用线程池: 1.减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务. 2.可以根据系统的承受能力,调整线程池中工作线线程的数 ...
- android线程池ThreadPoolExecutor的理解
android线程池ThreadPoolExecutor的理解 线程池 我自己理解看来.线程池顾名思义就是一个容器的意思,容纳的就是ThreadorRunable, 注意:每一个线程都是需要CPU分配 ...
- ThreadPoolExecutor的一点理解
整个ThreadPoolExecutor的任务处理有4步操作: 第一步,初始的poolSize < corePoolSize,提交的runnable任务,会直接做为new一个Thread的参数, ...
- Java 并发系列(一) ThreadPoolExecutor源码解析及理解
ThreadPoolExecutor 它是线程池最核心的类, 这里对核心的方法做简要的剖析(会持续更新),以加深对线程池运行原理的理解. 1. 核心成员变量及相关方法 // ctl非常重要,用整型表示 ...
- 深入理解java线程池—ThreadPoolExecutor
几句闲扯:首先,我想说java的线程池真的是很绕,以前一直都感觉新建几个线程一直不退出到底是怎么实现的,也就有了后来学习ThreadPoolExecutor源码.学习源码的过程中,最恶心的其实就是几种 ...
- ThreadPoolExecutor的一点理解 专题
corePoolSize(maxActiveThreadSize):线程池大小,决定着新提交的任务是新开线程云执行还是放到任务队列中,也是线程池的最最核心的参数.一般线程池开始时是没有线程的,只有当任 ...
- 多线程学习笔记-深入理解ThreadPoolExecutor
java多线程中,线程池的最上层接口是Executor,ExecutorService实现了Executor,是真正的管理线程池的接口,ThreadPoolExecutor间接继承了ExecutorS ...
- 理解ThreadPoolExecutor线程池的corePoolSize、maximumPoolSize和poolSize
我们知道,受限于硬件.内存和性能,我们不可能无限制的创建任意数量的线程,因为每一台机器允许的最大线程是一个有界值.也就是说ThreadPoolExecutor管理的线程数量是有界的.线程池就是用这些有 ...
随机推荐
- 7-13 航空公司VIP客户查询 (25 分)
题意: 思路: 读完题目之后的第一思路就是用map将客户的id(string类型)与里程road(int类型)形成映射,然后直接用id查找添加里程或输出里程.但是400ms的限制妥妥的超时了.然后意识 ...
- 内存_RAM或ROM_和FLASH存储的真正区别总结
http://blog.sina.com.cn/s/blog_4b37304d0100fg10.html
- 手机版地图api
手机版地图api一: <iframe style="height:300px;" src="http://map.baidu.com/mobile/webapp/s ...
- hdu2009 求数列的和【C++】
求数列的和 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submi ...
- mybatis源码阅读-初始化过程(七)
说明 mybatis初始化过程 就是解析xml到封装成Configuration对象 供后续使用 SqlSessionFactoryBuilder 代码例子 SqlSessionFactoryBuil ...
- request.getInputStream() 的两种解析方式
http://sagewsg.iteye.com/blog/1717923 byte[] bytes = new byte[1024 * 1024]; InputStream is; try { is ...
- oracle capability i/o(压力測试数据库serveri/o性能)
今天是2014-04-21,今天简单仅仅说明一下怎么影响重做数据的一个因素,那就是i/o吞吐量,oracle的介质恢复依赖于i/o,假设i/o存在瓶颈,那么势必会影响备库的介质恢复. 那么i/o st ...
- hdu 1050 Moving Tables(迷之贪心...)
题意:有400间房间按题目中图片所给的方式排列,然后给出要移动的n张桌子所要移动的范围,每张桌子要移动的范围不能出现重叠的区域:问最少要多少次才能移动完所有的桌子. 题解思路:把题目转换下,就是有n个 ...
- android graphic(15)—fence
为何须要fence fence怎样使用 软件实现的opengl 硬件实现的opengl 上层使用canvas画图 上层使用opengl画图 下层合成 updateTexImage doComposeS ...
- luogu2157 [SDOI2009]学校食堂 局部状压
题目大意 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负整数 ...