ThreadPoolExecutor线程池参数设置大多是参考别人的,只是在这里记录下
在ThreadPoolExecutor类中有四个不同参数的构造函数去获取线程池对象
最多7个参数,下面就来介绍下这7个参数的意义以及设置
首先看下参数意义:(这是源码对应的构造函数以及参数)
/**
* Creates a new {@code ThreadPoolExecutor} with the given initial
* parameters.
*
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
1.corePoolSize:要保留在池中的线程数,即使它们处于空闲状态,除非设置了
allowCoreThreadTimeOut
* 核心线程会一直存活,及时没有任务需要执行
* 当线程数小于核心线程数时,即使有线程空闲,线程池也会优先创建新线程处理
* 设置allowCoreThreadTimeout=true(默认false)时,核心线程会超时关闭
* @param maximumPoolSize the maximum number of threads to allow in the
* pool
2.maximumPoolSize:池中允许的最大线程数
* 当线程数>=corePoolSize,且任务队列已满时。线程池会创建新线程来处理任务
* 当线程数=maxPoolSize,且任务队列已满时,线程池会拒绝处理任务而抛出异常
* @param keepAliveTime when the number of threads is greater than
* the core, this is the maximum time that excess idle threads
* will wait for new tasks before terminating.
3.keepAliveTime:当线程数大于核心数时,这是多余的空闲线程在终止前等待新
任务的最长时间。
* 当线程空闲时间达到keepAliveTime时,线程会退出,直到线程数量=corePoolSize
* 如果allowCoreThreadTimeout=true,则会直到线程数量=0
* @param unit the time unit for the {@code keepAliveTime} argument
4.unit(TimeUnit):{@code keepAliveTime} 参数的时间单位
*设置参数3的单位时分秒天等单位
* @param workQueue the queue to use for holding tasks before they are
* executed. This queue will hold only the {@code Runnable}
* tasks submitted by the {@code execute} method.
5.workQueue:用于在执行任务之前保存任务的队列。该队列将仅保存由
{@code execute} 方法提交的 {@code Runnable} 任务
* @param threadFactory the factory to use when the executor
* creates a new thread
6.threadFactory:执行程序创建新线程时使用的工厂
* @param handler the handler to use when execution is blocked
* because the thread bounds and queue capacities are reached
7.handler:由于达到线程边界和队列容量而阻塞执行时要使用的处理程序
* @throws IllegalArgumentException if one of the following holds:<br>
* {@code corePoolSize < 0}<br>
* {@code keepAliveTime < 0}<br>
* {@code maximumPoolSize <= 0}<br>
* {@code maximumPoolSize < corePoolSize}
* @throws NullPointerException if {@code workQueue}
* or {@code threadFactory} or {@code handler} is null
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
}
详细解说下workQueue(BlockingQueue<Runnable> 的创建):
ArrayBlockingQueue
先进先出,阻塞队列,插入元素时队列满了会一直等待。新元素插入到队列的尾部,
队列获取操作则是从队列头部开始获得元素。
SynchronousQueue
数组结构的阻塞队列。队列满了以后,任何一次插入操作的元素都要等待相对的删除/读取操作。
LinkedBlockingQueue
先进先出,链表结构非阻塞队列,适合插入和删除较多的操作。
DelayedWorkQueue
延迟队列,延迟的时间还未到的获取的任务会返回空。
PriorityBlockingQueue
优先级队列,元素必须实现Comparable接口,优先级最高的始终在队列的头部,任务会优先执行。
详细说下handler(RejectedExecutionHandler的创建),以下都是队列满了以后,新任务的处理方式,也可以自己实现RejectedExecutionHandler去自定义。
1.AbortPolicy
如果线程池队列满了丢掉这个任务并且抛出RejectedExecutionException异常,源码如下:
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
throw new RejectedExecutionException("Task " + r.toString() +
" rejected from " + e.toString());
}
2.DiscardPolicy
队列满了任务直接丢掉,什么也不错。
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
}
3.DiscardOldestPolicy
队列满了以后,移除掉头部的元素,再尝试加入新元素。
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
e.getQueue().poll();
e.execute(r);
}
}
4.CallerRunsPolicy
队列满了以后,主线程自己去运行。
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
r.run();
}
}
下面说下ThreadPoolExecutor执行顺序
线程池按以下行为执行任务
1. 当线程数小于核心线程数时,创建线程。
2. 当线程数大于等于核心线程数,且任务队列未满时,将任务放入任务队列。
3. 当线程数大于等于核心线程数,且任务队列已满
- 若线程数小于最大线程数,创建线程
- 若线程数等于最大线程数,抛出异常,拒绝任务
ThreadPoolExecutor参数图解,可以参考下面链接,详细介绍了各个参数,
链接:https://blog.youkuaiyun.com/u011916937/article/details/107041519