线程池概述

优点:
1、线程池里面的线程是可复用的,不需要每次执行异步任务时都重新创建和销毁线程。

当执行大量异步任务时线程池能够提供较好的性能。在不使用线程池时,每当需要执行异步任务时直接new一个线程来运行,而线程的创建和销毁是需要开销的。

2、线程池提供了一种资源限制和管理的手段,比如可以限制线程的个数,动态新增线程等

类图

image.png
ThreadPoolExecutor继承了AbstractExecutorService,成员变量ctl是一个Integer的原子变量,用来记录线程池状态和线程池中线程个数。假设Integer类型是32位二进制表示,则其中高3位用来表示线程池状态,后面29位用来记录线程池线程个数。
image.png
mainLock是独占锁,用来控制新增Worker线程操作的原子性。
termination是该锁对应的条件队列,在线程调用awaitTermination时用来存放阻塞的线程。
Worker继承AQS和Runnable接口,是具体承载任务的对象。
Worker继承了AQS,自己实现了简单不可重入独占锁,
state=0表示锁未被获取状态
state=1表示锁已经被获取的状态
state=-1是创建Worker时默认的状态,创建时状态设置为-1是为了避免该线程在运行runWorker()方法前被中断。
变量firstTask记录该工作线程执行的第一个任务
thread是具体执行任务的线程。
DefaultThreadFactory是线程工厂
newThread方法是对线程的一个修饰。
其中poolNumber是个静态的原子变量,用来统计线程工厂的个数
threadNumber用来记录每个线程工厂创建了多少线程,这两个值也作为线程池和线程的名称的一部分。

线程池状态

状态 含义
RUNNING 接收新任务并处理阻塞队列里的任务
SHUTDOWN 拒绝新任务但处理阻塞队列里的任务
STOP 拒接新任务抛弃阻塞队列里的任务,并中断正在处理的任务
TIDYING 所有任务都执行完成(包括阻塞队列里的任务)后,当前线程池活动线程数为0,将要调用terminate方法
TERMINATED 终止状态,调用terminete方法之后的状态

线程池——ThreadPoolExecutor原理探究 - 图3

线程池参数

参数 含义
corePoolsize 线程池核心线程个数
workQueue 用于保存等待执行的任务的阻塞队列,比如基于数组的有界ArrayBlockingQueue、基于链表的无界LinkedBlockingQueue、最多只有一个元素的同步队列SynchronousQueue及优先级队列PriorityBlockingQueue等。
maximunPoolSize 线程池最大线程数
TreadFactory 创建线程工厂
RejectedExecutionHandler 饱和策略,当队列满并且线程个数达到maximunPoolSize后采取的策略,比如AbortPolicy(抛出异常)、CallerRunsPolicy(使用调用者所在线程来运行任务)、DiscardOldestPolicy(调用poll丢弃一个任务,执行当前任务)及DiscardPolicy(默默丢弃,不抛出异常)
keeyAliveTime 存活时间。如果当前线程池中的线程数量比核心线程数量多,并且是闲置状态,则这些闲置的线程能存活的最大时间。
TimeUnit 存活时间的时间单位。

线程池类型

线程池
newFixedThreadPool 创建一个核心线程个数和最大线程个数都为nThreads的线程池,并且阻塞队列长度为Integer.MAX_VALUE。keeyAliveTime=0说明只要线程个数比核心线程个数多并且当前空闲则回收
newSingleThreadExecutor 创建一个核心线程个数和最大线程个数都为1的线程池,并且阻塞队列长度为Integer.MAX_VALUE。keeyAliveTime=0说明只要线程个数比核心线程个数多并且当前空闲则回收。
newCachedThreadPool 创建一个按需创建线程的线程池,初始线程个数为0,最多线程个数为Integer.MAX_VALUE,并且阻塞队列为同步队列。keeyAliveTime=60说明只要当前线程在60s内空闲则回收。这个类型的特殊之处在于,加入同步队列的任务会被马上执行,同步队列里面最多只有一个任务。

源码

public void execute(Runnable command):
execute方法的作用是提交任务command到线程池进行执行。