Excutors 与 ThreadPoolExcutor 的关系与区别
先说结论。
线程池的创建分为两种:
Executors
ThreadPoolExecutor
Executors
是一个线程池的工具类,而 ThreadPoolExecutor
是 Executors
的具体实现。ThreadPoolExecutor
是 Executor
接口的一个实现,是线程池的核心类。Executors
工具类提供了很多方法来创建不同类型的线程池,比如 newFixedThreadPool
(创建固定线程数的线程池)、newCachedThreadPool
(创建缓冲线程池)、newSingleThreadPool
(创建只有一个线程的线程池)等,但内部都是通过构造 ThreadPoolExecutor
的不同参数实例来构造线程池的。
所以 Executors
适用于想快速创建一个线程池而不在意内部实现的场景,而 ThreadPoolExecutor
更为灵活可控,可自定义创建拥有特定配置的线程池。
说完的结论再来详细说说 Executors
和 ThreadPoolExecutor
。
Executors
Executors 创建线程池的方式有以下几种:
Executors.newFixedThreadPool
:创建固定大小的线程池Executors.newWorkStealingPool
:创建抢占式线程池Executors.newSingleThreadExecutor
:创建单个线程的线程池Executors.newCachedThreadPool
:创建可缓存的线程池Executors.newSingleThreadScheduledExecutor
:创建单线程可执行延迟任务的线程池Executros.newScheduledThreadPool
:创建可执行延迟任务的线程池
可以看下源码:
public class Executors {
/**
* 创建可重用的固定数量的线程池。如果所有线程都处在活动状态,提交额外任务
* 的时候,超出的线程在队列中等待。队列类型是 LinkedBlockingQueue
* nThreads 为创建线程池的数量
*/
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
/**
* Java 8 新增的线程池,具有抢占式操作的线程池,每个线程都有一个任务队列存放任务,
* 当线程发现自己的队列没有任务了,也就是先工作完了的线程就去帮助没处理完的线程工作。
* 以实现最快完成工作。
* 是基于 ForkJoinPool 创建的线程池,parallelism 参数自定义并行度。
*/
public static ExecutorService newWorkStealingPool(int parallelism) {
return new ForkJoinPool
(parallelism,
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
/**
* 同上,但是并行度是根据获取当前系统的 CPU 核心数来判断。
*/
public static ExecutorService newWorkStealingPool() {
return new ForkJoinPool
(Runtime.getRuntime().availableProcessors(),
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
/**
* 创建固定数量线程的线程池,可控制线程最大并发数,超出的线程会在队列中等待。
* 多了一个 ThreadFactory 参数,线程工厂,主要用来创建线程池
*/
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
}
/**
* 创建单个线程的线程池。它可以保证先进先出的执行顺序。
*/
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
/**
* 同上。
*/
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory));
}
/**
* 创建一个可缓存的线程池。适用于短期执行的异步任务,从代码中可以看出线程数的设定是
* Integer.MAX_VALUE,不对线程池的大小做设定,可以创建无限数量的线程。
* 但也就不适合执行长时间运行的任务,可能会导致系统资源耗尽。
*/
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
/**
* 同上
*/
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
threadFactory);
}
/**
* 创建一个单线程的可以执行延迟任务的线程池,可以安排以给定延迟后执行的命令或定时执行的命令。
*
*/
public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
return new DelegatedScheduledExecutorService
(new ScheduledThreadPoolExecutor(1));
}
/**
* 同上
*/
public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
return new DelegatedScheduledExecutorService
(new ScheduledThreadPoolExecutor(1, threadFactory));
}
/**
* 创建一个可以执行延迟任务的线程池,任务数量自定义
*/
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
/**
* 同上
*/
public static ScheduledExecutorService newScheduledThreadPool(
int corePoolSize, ThreadFactory threadFactory) {
return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
}
}
可以看到其实 Executors
创建的线程大部分都是由 ThreadPoolExecutor
实现。
ThreadPoolExecutor
直接看下他的构造函数:
public ThreadPoolExecutor(int corePoolSize, // 核心线程数,线程池中始终存活的线程数
// 最大线程数,线程池中允许的最大线程数
int maximumPoolSize,
// 最大线程数可以存活的时间
long keepAliveTime,
// 时间单位
TimeUnit unit,
// 阻塞队列,workQueue 包含七种
BlockingQueue<Runnable> workQueue,
// 线程工厂,主要用来创建线程
ThreadFactory threadFactory,
// 拒绝策略
RejectedExecutionHandler handler ) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
this.prestartAllCoreThreads();
}
ThreadPoolExecutor
的执行原理如图:
本文来自博客园,作者:knqiufan,转载请注明原文链接:https://www.cnblogs.com/knqiufan/p/18089234