线程池参数详解
我们知道JUC提供了丰富的并发工具类,其中类似于组的结构叫做线程池。就是说我们可以将我们需要运行的线程加入到这个组内,然后通过启动线程池来执行加入到线程池的所有任务。既然是容器,那么必然会有很多参数为容器运行的界定边界。那么这些参数又有什么意义?通过理解这些参数我们也可以从侧面了解线程池的逻辑形式和运行机理。
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
上述代码是用来初始化一个ThreadPoolExecutor,也就是线程池执行器。因为线程池并不单单是容器,还是还有很多操作线程的方法。
其主要的参数有corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory、handler
其中
corePoolSize很好理解,就是核心线程数。也就是在线程池中肯定存在的线程数。
maximumPoolSize是最大线程数。就是随着加入线程池的线程越来越多线程池创建的线程会越来越多,那么索要创建的线程数目的上限是是多少。这个数字就是用来描述这个的。
现在最小和最大都有的还缺什么?
我们看到keepAliveTime,keepAliveTime是用来描述线程销毁的闲置时间量,如果任务加入到线程池线程池的核心线程在处理其他任务。所以线程池创建了新的线程。但是新线程处理完毕该任务之后等待了keepAliveTime时间没有新任务。那么该线程就会销毁。allowCoreThreadTimeout是用来描述核心线程时候可以在keepAliveTime时间的空闲中退出。其中传入的参数unit也就是一个处理keepAliveTime的工具罢了。
workQueue从字面上理解应该是工作队列。而且这个队列是BlockingQueue,我们之前学过BlockingQueue的类型。LinkedBlockingDeque、ArrayBlockingQueue、PriorityBlockingQueue、SynchronousQueue。这里要求我们传入的是Runable类型,也就是传入的是任务。回顾一下我们上学时候学的Thread类,那么Thread就是线程了,而runable则是执行的任务了。那么WorkQueue应该就是我们提交的任务的存储容器。如果核心线程再处理任务。那么就会创建新线程处理提交的任务。如果线程的数量达到了maximumPoolSize之后就不再创建线程,也就是再来的任务就会加入到这个队列中。等待线程执行。如果超过了这个容量估计会会拒绝任务的提交。
threadFactory是线程工厂,主要用来创建线程。
handler是拒绝策略,也就是上边说的任务队列满了之后线程池的响应策略。那么这个策略应该是可以自定义或者提供了比较常用的方式。
- wpf 控件大小随窗体大小改变而改变
- 零基础学编程036:快速编写一个GUI程序
- WPF TreeView 选择事件执行两次,获取TreeView的父节点的解决方法
- 零基础学编程041:欧拉公式的几何意义
- 零基础学编程040:在Windows上安装Python库的正确姿势
- c++/c 获取cpp文件行号跟文件名
- 零基础学编程042:画函数图像
- C-SATS工程副总裁教你如何用TensorFlow分类图像 part2
- C++11 Lambda表达汇总总结
- TensorFlow开发环境搭建(Ubuntu16.04+GPU+TensorFlow源码编译)
- C++虚析构函数解析
- C-SATS工程副总裁教你如何用TensorFlow分类图像 part1
- 帝国cms文章页调用当前文章URL如何操作?
- dedecms文章页调用地址(当前文章URL)如何操作?
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 本周AI热点回顾:RTX3080被黄牛炒上天;百度资本助力AI 制药,已有十几位博士加入;百度联手打造AI沉浸互动展中国首秀
- 线段树
- 乘法表中第k小的数
- 数据可视化 | Pandas vs Plotnine
- laravel里使用chunk的一个坑
- 一个小小的签到功能,到底用 MySQL 还是 Redis ? ?
- 下载丨9月数据库技术通讯:Redo日志丢失,重建遭遇ORA-16433处理
- knative serving 组件分析
- 在 minikube 上部署 knative
- 认识 JS 静态类型检查工具 Flow
- PostgreSQL中如何实现密码复杂度检查?
- JS/TS 对数组中的对象按对象的值进行去重
- JS/TS 对数组中的对象按相同值进行分组
- CSS 实现输入框从右往左和反向倒序输入
- SAP Spartacus PagelayoutComponent里的template