ThreadPoolExcutor的核心参数
首先来回忆下线程池的几个核心参数;
- corePoolSize:核心线程数
- maximumPoolSize:最大线程数
- keepAliveTime:线程空闲时间
- TimeUnit:时间单位
- workQueue:线程工作队列
- ThreadFactory:线程创建工厂
- RejectedExecutionHandler:线程拒绝策略
这些也是我们日常使用线程池,所需要关注的一些参数配置,具体配置的大小,需要根据我们实际服务器的实际情况,这里就做简单了解下,就不过多于纠结了,分为两种情况:
- IO密集型配置线程数经验值是:2N,其中N代表CPU核数。
- CPU密集型配置线程数经验值是:N + 1,其中N代表CPU核数。
ThreadPoolExcutor线程池的线程数执行情况
我们通过配置线程池的参数,结合提交的任务数,来去观察任务数、核心线程数、最大线程数和队列之间的变化;
创建线程池
ini
public class ThreadPoolTest {
public static void main(String[] args) {
//定义一个线程池 核心线程数为4,最大线程数为6,队列长度为2
BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2);
ThreadPoolExecutor poolExecutor =new ThreadPoolExecutor(4,6,0L, TimeUnit.MILLISECONDS
,workQueue);
// 任务数 3-9
int work =9;
for (int i = 1; i <= work; i++) {
int workCount =i;
poolExecutor.submit(new Runnable() {
@Override
public void run() {
// Thread thread =Thread.currentThread();
// String threadName =thread.getName();
// int activeCount = poolExecutor.getActiveCount();
// System.out.println("当前任务:"+workCount+",线程名称"+threadName+",活跃线程数:"+activeCount);
System.out.println(Thread.currentThread().getName());
try{
Thread.sleep(300000L);
}catch (InterruptedException ex){
ex.printStackTrace();
}
}
});
System.out.println("当前任务:"+workCount+",创建第" + i + "个线程后, 线程池情况:" + poolExecutor.toString());
}
}
}
执行结果:
- 第一种情况:任务数为3,核心线程数为4,最大线程数为6; 任务数<核心线程数; 执行main方法,可以得到活跃的线程数为3个线程
- 第二种情况:任务数为4,核心线程数为4,最大线程数为6;任务数=核心线程数; 执行main方法,可以得到活跃线程为4;
- 第三种情况:任务数为5,核心线程数为4,最大线程数为6;任务数>核心线程数,<最大线程数6,会将多出来1个的任务放入在队列等待; 执行main方法,相当于任务数 <核心线程数4+队列长度2, 可以得到活跃线程为4;
- 第四种情况:任务数为6,核心线程数为4,最大线程数为6;任务数 =核心线程数,=最大线程数6,会将多出来的任务放入在队列等待; 执行main方法,相当于任务数 =核心线程数4+队列长度2, 可以得到活跃线程为4;
- 第五种情况:任务数为7,核心线程数为4,最大线程数为6;任务数 >核心线程数,>最大线程数6; 执行main方法,相当于任务数 <最大线程数6+队列长度2, 此时任务数为7,线程池会开启4个核心线程执行4个任务,2个任务放入队列等待,此还有一个任务没有执行,但是小于最大线程数6,会再开启一个活跃线程去执行这1一个任务,所以总共活跃线程就是5;
- 第六种情况:任务数为8,核心线程数为4,最大线程数为6;任务数 =最大核心线程数6+队列2;活跃线程数就是6;
- 第七种情况:任务数为9,核心线程数为4,最大线程数为6;任务数 >最大核心线程数6+队列2;可以看到在执行到第8个任务的时候,活跃线程数为6,等待队列任务为2,执行到第9个任务的时候,由于任务数 9 >最大核心线程数6+队列2,所以触发了拒绝策略;
总结
在正常情况下,线程池内活跃线程数>核心线程数时,后面进来的任务会加入队列中等待,如果队列已满,会新建线程直到线程池内线程数等于最大线程数,如果还有新的任务进行提交,那么将会触发默认的拒绝策略,AbortPolicy 拒绝创建;