请讲一下线程池的创建方法,并介绍里面几个参数的作用,并讲讲你对里面的队列的了解。
创建线程池有四种方法:
方法 | 描述 |
---|---|
Executors.newFiexedThreadPool(int Threads) | 创建固定数目线程的线程池。 |
Executors.newCachedThreadPool() | 创建一个可缓存的线程池,调用 exxecute 将重以前构造的线程。如果没有线程则创建一个新的线程并且添加到池中。 |
Excutors.newSingleThreadExecutor() | 创建一个单线程。 |
Excutors.newScheduledThreadPool(int corePoolSize) | 创建一个支持定时及周期性的任务执行的线程池。 |
用 Executors 方式创建线程的时候操作不当会有 OOM 的问题,主要是其创建线程池的时候用的是 LinkedBlockingQueue,是一个无界队列。一般建议用以下方式创建线程池:
public ThreadPoolExecutor(int corePoolSize, // 1
int maximumPoolSize, // 2
long keepAliveTime, // 3
TimeUnit unit, // 4
BlockingQueue<Runnable> workQueue, // 5
ThreadFactory threadFactory, // 6
RejectedExecutionHandler handler ) { //7
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 | int | 核心线程池大小 |
maximumPoolSize | int | 最大线程池大小 |
keepAliveTime | long | 线程最大空闲时间 |
unit | TimeUnit | 时间单位 |
workQueue | BlockingQueue |
线程等待队列 |
threadFactory | ThreadFactory | 线程创建工厂 |
handler | RejectedExecutionHandler | 拒绝策略 |
线程池创建过程中先将创建的线程放在核心线程池里面,如果核心线程池放满了,会将线程放在线程等待队列里面,如果线程等待队列也放满了,会将线程往线程池里面放,直到数量达到最大线程池大小。这个时候如果还有新的线程过来,会执行相应的拒绝策略。
BlockingQueue 包含下面几种:
队列名称 | 意义 |
---|---|
ArrayBlockingQueue | 基于数组结构的有界阻塞队列,此队列按 FIFO 原则对元素进行处理 |
LinkedBlockingQueue | 一个基于链表结构的无界有序阻塞队列,按照 FIFO 排序元素 |
SynchronousQueue | 不存储元素的阻塞队列,每一个插入必须等到前一个元素被移除 |
PriorityBlockingQueue | 有优先级的无限阻塞队列 |
RejectedExecutionHandler 包含以下几种:
拒绝策略名称 | 含义 |
---|---|
AbortPolicy | 如果线程池队列满了,并且最大线程数也满了,就将这个任务丢弃,并且抛出异常 |
DiscardPolicy | 如果队列满了,并且最大线程数也满了,就直接将任务丢弃,不会有任何异常 |
DiscardOldestPolicy | 如果队列满了,而且最大线程数也达到了,会将老的线程丢弃,接收新的线程 |
CallerRunsPolicy | 如果添加失败,当前的主任务来处理该线程操作。 |
自定义 | 自己定义一个拒绝策略,实现 RejectedExecutionHandler 接口 |