线程池概述
优点:
1、线程池里面的线程是可复用的,不需要每次执行异步任务时都重新创建和销毁线程。
当执行大量异步任务时线程池能够提供较好的性能。在不使用线程池时,每当需要执行异步任务时直接new一个线程来运行,而线程的创建和销毁是需要开销的。
2、线程池提供了一种资源限制和管理的手段,比如可以限制线程的个数,动态新增线程等
类图

ThreadPoolExecutor继承了AbstractExecutorService,成员变量ctl是一个Integer的原子变量,用来记录线程池状态和线程池中线程个数。假设Integer类型是32位二进制表示,则其中高3位用来表示线程池状态,后面29位用来记录线程池线程个数。
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方法之后的状态 |
线程池参数
| 参数 | 含义 |
|---|---|
| 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到线程池进行执行。
