Java线程池maximumPoolSize和workQueue哪个先饱和?
先说结论,真正的饱和顺序是corePoolSize -> workQueue -> maximumPoolSize。
我们都知道,线程池有以下参数
ThreadPoolExecutor(int corePoolSize, //核心线程数
int maximumPoolSize, //
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue)
- corePoolSize:核心线程池大小,即使没有任务,这些线程也会一直存活。
- maximumPoolSize:最大线程池大小,当任务量超过核心线程数时,最多可以创建这么多线程。
- keepAliveTime:非核心线程在空闲时等待新任务的最长时间。
- unit:keepAliveTime 的时间单位。
- workQueue:阻塞队列,用于存储待执行的任务。常见的阻塞队列实现有 ArrayBlockingQueue、LinkedBlockingQueue 和 SynchronousQueue 等。
我之前的理解是,当线程数达到corePoolSize后,新任务到来会创建新线程直到达到maximumPoolSize,当达到maximumPoolSize后,新任务才会放到workQueue里。
但其实,这一直都是错误的理解,真正的饱和顺序是corePoolSize->workQueue->maximumPoolSize。
下面开始验证
ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10));
for (int i = 0; i < 6; i++) {
int finalI = i;
executor.submit(() -> {
System.out.println(Thread.currentThread().getName() + " " + finalI);
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
}
executor.shutdown();
若corePoolSize满了后新任务是创建新线程,那么这里应该一次打印6条日志。
若corePoolSize满了之后新任务放到workQueue里,那么这里应该打印两次,第一次5条,第二次1条。
打印结果
由此可见符合第二种情况,为了证明可信度下面再验证一种情况
ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10));
for (int i = 0; i < 16; i++) {
int finalI = i;
executor.submit(() -> {
System.out.println(Thread.currentThread().getName() + " " + finalI);
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
}
executor.shutdown();
按照上面的结论推测,当我们有16个要执行的任务,首先会占用5个核心线程,然后放10个任务到阻塞队列,剩下的1个加上核心线程数是6个,达不到最大线程数,所以会创建活动线程,此时线程池中会有6个可用线程。所以会分三次打印结果,第一次6条,第二次6条,第三次4条。下面验证推测
验证成功!
Java线程池maximumPoolSize和workQueue哪个先饱和?的更多相关文章
- Java 线程池框架核心代码分析--转
原文地址:http://www.codeceo.com/article/java-thread-pool-kernal.html 前言 多线程编程中,为每个任务分配一个线程是不现实的,线程创建的开销和 ...
- Java线程池使用说明
Java线程池使用说明 转自:http://blog.csdn.net/sd0902/article/details/8395677 一简介 线程的使用在java中占有极其重要的地位,在jdk1.4极 ...
- [转 ]-- Java线程池使用说明
Java线程池使用说明 原文地址:http://blog.csdn.net/sd0902/article/details/8395677 一简介 线程的使用在java中占有极其重要的地位,在jdk1. ...
- 【Java线程池快速学习教程】
1. Java线程池 线程池:顾名思义,用一个池子装载多个线程,使用池子去管理多个线程. 问题来源:应用大量通过new Thread()方法创建执行时间短的线程,较大的消耗系统资源并且系统的响应速度变 ...
- Java 线程池框架核心代码分析
前言 多线程编程中,为每个任务分配一个线程是不现实的,线程创建的开销和资源消耗都是很高的.线程池应运而生,成为我们管理线程的利器.Java 通过Executor接口,提供了一种标准的方法将任务的提交过 ...
- java线程池的使用与详解
java线程池的使用与详解 [转载]本文转载自两篇博文: 1.Java并发编程:线程池的使用:http://www.cnblogs.com/dolphin0520/p/3932921.html ...
- Java线程池使用和分析(一)
线程池是可以控制线程创建.释放,并通过某种策略尝试复用线程去执行任务的一种管理框架,从而实现线程资源与任务之间的一种平衡. 以下分析基于 JDK1.7 以下是本文的目录大纲: 一.线程池架构 二.Th ...
- Java线程池使用和分析(二) - execute()原理
相关文章目录: Java线程池使用和分析(一) Java线程池使用和分析(二) - execute()原理 execute()是 java.util.concurrent.Executor接口中唯一的 ...
- java线程池ThreadPoolExector源码分析
java线程池ThreadPoolExector源码分析 今天研究了下ThreadPoolExector源码,大致上总结了以下几点跟大家分享下: 一.ThreadPoolExector几个主要变量 先 ...
- Java线程池带图详解
线程池作为Java中一个重要的知识点,看了很多文章,在此以Java自带的线程池为例,记录分析一下.本文参考了Java并发编程:线程池的使用.Java线程池---addWorker方法解析.线程池.Th ...
随机推荐
- MaxCompute管家详解--管家助力,轻松玩转MaxCompute
精彩视频回顾请点击:MaxCompute管家详解以下是直播内容精华整理,主要包括以下四个方面:1.背景速览:2.功能介绍:3.案例讲解:4.新功能预告. 一.背景速览 MaxCompute(原ODPS ...
- Fluid — 云原生环境下的高效“数据物流系统”
简介: 为了解决大数据.AI 等数据密集型应用在云原生计算存储分离场景下,存在的数据访问延时高.联合分析难.多维管理杂等痛点问题,南京大学 PASALab.阿里巴巴.Alluxio 在 2020 年 ...
- 10种编程语言实现Y组合子
简介: Y组合子是Lambda演算的一部分,也是函数式编程的理论基础.它是一种方法/技巧,在没有赋值语句的前提下定义递归的匿名函数,即仅仅通过Lambda表达式这个最基本的"原子" ...
- ADBPG&Greenplum成本优化之磁盘水位管理
简介:本文我们将通过一个实际的磁盘空间优化案例来说明,如何帮助客户做成本优化. 作者 | 玉翮 来源 | 阿里技术公众号 一 背景描述 目前,企业的核心数据一般都以二维表的方式存储在数据库中.在 ...
- 揭秘远程证明架构EAA:机密容器安全部署的最后一环 | 龙蜥技术
简介:如果需要在云上 HW-TEE 环境里启动一个加密容器,如何在启动过程中获取容器的解密密钥? 文 / 周亮, 云原生机密计算 SIG 核心成员. 在云原生场景下,基于HW-TEE(如Inte ...
- 分布式系统一致性测试框架Jepsen在女娲的实践应用
简介: 女娲团队在过去大半年时间里持续投入女娲2.0研发,将一致性引擎和业务状态机解耦,一致性引擎可支持Paxos.Raft.EPaxos等多种一致性协议,根据业务需求支撑不同的业务状态机.其中的一 ...
- [GPT] export, export default, import, module.exports, require
ES6 规范:export 和 import 配对 import 的 {} 大括号里面指定要从其他模块导入的变量名, 如果 export 命令没有写 default,那么 import {} 大括号里 ...
- DB2查找最耗时SQL
两种方法:db2top和snapshot for dynamic sql 1. db2top -d <dbname>
- golang计时器
timer 计时器 用于在指定的Duration类型时间后调用函数或计算表达式. 如果只是想指定时间之后执行,使用time.Sleep() 使用NewTimer(),可以返回的Timer类型在计时器到 ...
- 07. C语言程序执行流程控制
[有条件执行语句] if esle 语句 if else 语句根据一个条件确定是否执行一段代码,执行条件是一个布尔值,布尔值为true则执行,为false则不执行,同时可以设置不符合条件时执行的语句. ...