线程池核心:三大方法、七大参数、四种拒绝策略
池化技术
所谓的池化技术,通俗来讲就是:提前准备好资源,要用就从这里拿,用完再换回来。这样做的好处:对于那写创建销毁很费时的资源,可以减少这方面时间的消耗,优化资源利用。
线程池
主要解决两个问题:
- 当执行大量异步任务时线程池能提供较好的性能。(线程的复用)
- 线程池提供了一种资源限制和管理的手段。(如线程的个数)
好处:
1、降低资源的消耗
2、提高相应的速度
3、方便管理
4、线程复用、可以控制最大并发数、管理线程
线程池三大方法(不推荐使用)
//三种方法
ExecutorService threadPool = Executors.newSingleThreadExecutor();//单例,只有一个线程
ExecutorService threadPool = Executors.newFixedThreadPool(5);//固定,可以创建有指定数量的线程
ExecutorService threadPool = Executors.newCachedThreadPool();//缓存,程序根据情况创建线程数量
可以看出三种方法都基于Executors。Executors其实是一个工具类,它提供了很多静态方法,可根据用户的选择返回不同的线程池实例。
在阿里巴巴开发手册中 (不允许使用Executors)

所谓的OOM指的是OutOfMemoryError,ThreadPoolExecutor会在下面介绍到。
三大方法源码分析
- newSingleThreadExecutor()
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
- newFixedThreadPool()
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
- newCachedThreadPool()
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
通过源码可以发现:三大方法本质上返回的都是一个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;
}
七大参数
ThreadPoolExecutor各参数的涵义:
public ThreadPoolExecutor(int corePoolSize,//核心线程池大小
int maximumPoolSize, //最大核心线程池大小
long keepAliveTime, // 存活时间
TimeUnit unit, // 超时单位
BlockingQueue<Runnable> workQueue, // 阻塞队列
ThreadFactory threadFactory, //线程工厂
RejectedExecutionHandler handler //拒绝策略)
- corePoolSize:核心线程池大小。线程池的基本大小,在没有任务执行时的大小,并且只有当线程工作队列满了后才会创建超出这个数量的线程。
- maximumPoolSize:最大线程池大小。创建线程的数量不会超过maximumPoolSize的值。
- keepAliveTime:存活时间。超过了这个时间如果还没有被调用就会释放。
- unit:超时单位。设置keepAliveTime的单位。
- workQueue:阻塞队列。用于保存执行的任务的阻塞队列。(如基于数组的有界ArrayBlockingQueue、基于链表的无界LinkedBlocking、同步队列SynchronousQueue、优先级队列PriorityBlockingQueue)
- threadFactory:线程工厂。用于创建线程,一般大多数情况下默认情况 Executors.defaultThreadFactory()。
- handler:线程池拒绝策略。当队列满并且线程个数达maximumPoolSize后会采取的策略。有四种拒绝策略AbortPolicy() 、 CallerRunsPolicy() 、 DiscardPolicy() 、 DiscardOldestPolicy()
读者可以根据七大参数去分析上面三大方法中的参数。
四种拒绝策略
在七大参数中提到:当队列满并且线程个数达maximumPoolSize后会采取拒绝策略。
ThreadPoolExecutor中有四个静态内部类实现了RejectedExecutionHandler,对应的就是四种拒绝策略。

四种拒绝策略:
- AbortPolicy():抛出异常。当队列和最大线程数量都满了时,如果还有线程进来则不处理该线程并且抛出异常。
- CallerRunsPolicy():使用调用者所在线程来运行任务。“打发”给调用者所在线程。
- DiscardPolicy():默默丢弃,不抛出异常。
- DiscardOldestPolicy():调用poll丢弃一个任务,执行当前线程。(被拒绝后,将最早就入队列的任务删掉,再尝试加入队列)
ThreadPoolExecutor使用
@Test
public void test() {
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(1,5,60, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(3),new ThreadPoolExecutor.AbortPolicy());
try {
for (int i = 0; i < 5; i++) {
threadPool.execute(()->{
System.out.println(Thread.currentThread().getName());
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
threadPool.shutdown();
}
}

浙公网安备 33010602011771号