线程池存在的意义
线程是CPU的稀缺资源,而JAVA线程的创建与销毁都会导致操作系统的状态切换,这个过程会极大的消耗CPU资源,如果无限制的创建线程,还会降低系统的稳定性。为了避免过多的消耗资源,就需要设法重用线程,于是线程池的概念应运而生。
线程池:一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用,还能防止过分调度。
ThreadPoolExecutor源码详解
Java线程程是由实现的,它的相关继承关系如下图:
先来看一下它完整的构造函数:
/**
*
* @param corePoolSize 核心线程数量
* @param maximumPoolSize 最大线程数量
* @param keepAliveTime 非核心线程的最大存活时间
* @param unit keepAliveTime参数的单位
* @param workQueue 任务阻塞队列
* @param threadFactory 线程工厂
* @param handler 任务的拒绝策略
*/
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;
}
构造函数中有几大参数,解释如下:
corePoolSize:核心线程数量,核心线程是指线程池中永久存在的线程。
maximumPoolSize:最大线程数量,即线程池中允许存在的最大线程数量(包含核心线程)。
keepAliveTime:非核心线程的最大存活时间。
unit:keepAliveTime参数的计算单位。
workQueue:任务阻塞队列,用来存放等待分配线程的任务。
threadFactory:线程工厂,用来给任务分配线程。
handler:任务的拒绝策略,当任务既无法分配线程又无法放入阻塞队列时采取的策略。有如下4种:
- AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
- DiscardPolicy:丢弃任务但不抛出异常。
- DiscardOldestPolicy:丢弃阻塞队列中处在队头的任务,并把此任务加入队尾。
- CallerRunsPolicy:由调用主线程来执行此任务。
下面是