7大参数自定义线程池(核心线程数,最大核心线程数。。。拒绝策略(4种))
第一步:我们首先看单例线程池的源码
第二步:多个固定线程的线程池源码
第三步:可变的线程数的线程池源码
开启线程池的本质(调用ThreadPoolExecutor())
进去调用的this,再往下走
!!!走this方法里(可以看到有7个参数)
*corePoolSize:核心线程数
*maximumPoolSize:最大核心线程池大小(是包括前面的核心线程数的。前面为2,设置为5,那么旁边就是剩3个封存着的)
*keepAliveTime:超时无人调用就会释放
*TimeUnit:超时单位
*BlockingQueue<Runnable>:阻塞队列
*ThreadFactory:线程工厂,创建线程的(一般不用动)
*RejectExecutionHandler:拒绝策略(有四种的)
分析源码:
因为我们这个若是用的Executors去创建线程池的话,那么可以看到这个CachedThreadPool可能会创建大量的线程(最多21亿)从而导致OOM
!!!7大参数模型:(这里也说下线程池的运行逻辑)
首先我们线程池里面有几个东西这样说吧,核心线程数,最大线程数(阻塞队列吗,满了才开启的),阻塞队列,拒绝策略。
- 我们我们有任务进来,先看下核心线程是否有空闲,若是有空闲就用空闲线程来执行2、若是核心线程数都被占用,那么就会将任务放到阻塞队列
- 若是阻塞队列都放满了,那么我们就使用最大线程数的线程来执行
4、若是最大线程数也满了,那就4种拒绝策略拒绝咯
代码操作:
Executors默认使用AborPolicy(不处理,抛出异常)
第一步:5个人进去(2个核心数处理,3个再阻塞队列里面,最大5个个核心线程数(3个在等待阻塞队列满了唤醒))
两个核心线程在使用
第二步:进去6个人(就会使用2个核心线程和,一个最大线程数里的了,(3个再阻塞队列里))
同理7个线程,就会触发线程池中4个线程数处理。
9个就会触发拒接策略了(这里是不处理,抛出异常(5+3)线程池最多容纳8个线程)
里面最多5个核心线程数跑,然后最多容纳8个,有一个就拒绝策略,这里是不处理抛出异常(.AbortPolicy())
!!!第二种拒绝策略:(CallerRunsPolicy(哪来的去哪里))这里我们是main线程创建的,所以就是main线程去处理
看到没有是main去处理的,滚回去让创建你的处理去(拒绝策略)5个最大核心线程+main线程
!!第三个拒绝策略(DisCarPolict(队列满了,丢掉任务(不处理)不会抛出异常))
这里看到,没有处理,也不会抛出异常
拒绝策略4、(DiscardOldestPolicy(队列满了,尝试和最早的线程竞争,竞争失败就不执行咯(不是直接不执行),也是不会抛出异常的(是我们DIs上面的升级版嘛)))
没有抛出异常,尝试和最早的线程竞争
总结:
package org.example.threadpoolexecutor;
import java.util.concurrent.*;
public class TestThreadPoolSeven {
public static void main(String[] args) {
System.out.println(Runtime.getRuntime().availableProcessors());
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
2,//核心线程是
Runtime.getRuntime().availableProcessors(),//最大线程数
0L,//超时多久没人调用会释放
TimeUnit.MINUTES,//超时单位
new LinkedBlockingDeque<>(3),//阻塞队列(大小为3)
Executors.defaultThreadFactory(),//线程工厂,一般不会动
// new ThreadPoolExecutor.AbortPolicy());//超过容量,不处理抛出异常
// new ThreadPoolExecutor.CallerRunsPolicy());//超出容量,线程池不处理,返回给创建他的处理
// new ThreadPoolExecutor.DiscardPolicy());//不处理,直接丢弃。不抛异常
new ThreadPoolExecutor.DiscardOldestPolicy());//不直接抛弃,而是和最早的线程竞争线程
try {
for (int i = 1; i <=9; i++) {
threadPool.execute(()->{
System.out.println(Thread.currentThread().getName()+"=>ok");
});
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
threadPool.shutdown();
}