**ThreadPoolExecutor **
Java 线程池核心实现类有两个 一个是ThreadPoolExecutor ,还有一个工具类Executors 两个类都位于java.util.current包下
ThreadPoolExecutor 的顶层接口实现是 Executor
我们着重介绍ThreadPoolExecutor 类 先看下ThreadPoolExecutor 类的构造函数
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
这里面有7个参数
1、 corePoolSize 核心线程池数量
线程池创建后激活线程数量,不会被销毁
2、maximumPoolSize 最大线程数量
线程允许创建最大数量
3、keepAliveTime 线程存活时间
maximumPoolSize - corePoolSize 剩下多余线程 空闲时候 可允许存活时间
4、TimeUnit 时间单位
即线程存活时间 的单位 s ms 等等
5、BlockingQueue 阻塞队列
存放线程的可选队列
ArrayBlockingQueue :有界阻塞队列。此队列按照先进先出(FIFO)的原则对元素进行排序
LinkedBlockingQueue :一个由链表结构组成的有界阻塞队列。此队列的默认和最大长度为Integer.MAX_VALUE。此队列按照先进先出的原则对元素进行排序。
PriorityBlockingQueue :一个支持优先级排序的无界阻塞队列。
DelayQueue:延迟无界阻塞队列。元素的一个无界阻塞队列,只有在延迟期满时才能从中提取元素
SynchronousQueue:一个不存储元素的阻塞队列。一种阻塞队列,其中每个插入操作必须等待另一个线程的对应移除操作 ,反之亦然。
LinkedTransferQueue:一个由链表结构组成的无界阻塞队列。
LinkedBlockingDeque:一链表结构组成的双向阻塞队列。
6、defaultThreadFactory 默认线程工厂
线程创建工厂,一般使用默认就可以
7、defaultHandler 拒绝策略
当线程超出最大可接受线程数量可使用的可选策略
这里我们主要看concurrent 包下面的,我们看到有4种
- DiscardOldestPolicy 丢弃旧的未被处理的任务
- AbortPolicy 拒绝接受新的任务,并抛出异常
- CallerRunsPolicy 拒绝接受新的任务,但是新的任务会被以同步的方式继续执行
- DiscardPolicy
拒绝接受新的任务
执行顺序
比如 有这么一个线程池
new ThreadPoolExecutor(5, 30, 10, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>(50), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
上述线程池当有100个线程同时访问 怎么执行的
首先 立即执行有5个线程, 50个线程进入BlockingQueue 等待,
在开启45个新的线程执行 剩下的 20 个 执行拒绝策略
Executors
线程池工具类默认提供了一些创建好的线程池,比如
newFixedThreadPool 固定程线程池
newSingleThreadExecutor 单线程池
newCachedThreadPool 缓存线程池
方法 有很多 感兴趣的小伙伴 可自行去查看Executors 类的源码,这里不过多赘述
最后附上一段关于阿里巴巴开发手册上关于描述线程池的一段话,给各位小伙伴以后使用线程池做一份友好的建议哦
【强制】线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,
这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。