线程池介绍
- 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
- 提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
- 提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
线程池创建的两种方式
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;
}
简要说说我的理解,其中创建一个实例对象通常有以下4中构造方法,我们通常需要指定的是
- corePoolSize:指定线程池核心线程数。
- maximumPoolSize:线程池最大线程数。(和核心线程区别后面会讲)
- keepAliveTime:非核心线程执行完某一任务后,任务队列中没有要执行的任务分配给改线程,该线程不会立即销毁,而是会等待,直到等待的时间超过了
keepAliveTime
才会被回收销毁。 - TimeUnit:顾名思义,时间单位。
- workQueue:任务队列,是阻塞式的,用来存储待执行的任务。建议使用ArrayBlockingQueue,指定其大小,防止队列无限存储,产生OOM。
threadFactory
:executor 创建新线程的时候会用到。handler:
饱和策略。