ThreadPoolExecutor 介绍
线程池能够带来3个好处:
降低资源消耗:通过重复利用已创建的线程降低线程创建和销毁造成的消耗;
提高响应速度:当任务到达时,任务可以不需要等到线程创建就能立即执行;
提高线程的可管理性:线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一分配、调优和监控。

超过可容纳任务数后,按策略处理
可容纳任务数 = 最大线程数(maximumPoolSize)+ 最大队列数(workQueue.size())

线程资源必须通过线程池提供, 不允许在应用中自行显式创建线程。
说明: 线程池的好处是减少在创建和销毁线程上所消耗的时间以及系统资源的开销, 解决资源不足的问题。如果不使用线程池, 有可能造成系统创建大量同类线程而导致消耗完内存或者“过度切换” 的问题。
线程池不允许使用 Executors 去创建, 而是通过 ThreadPoolExecutor 的方式, 这样的处理方式让写的同学更加明确线程池的运行规则, 规避资源耗尽的风险。
说明: Executors 返回的线程池对象的弊端如下:
1) FixedThreadPool 和 SingleThreadPool:允许的请求队列长度为 Integer.MAX_VALUE, 可能会堆积大量的请求, 从而导致 OOM。
2) CachedThreadPool:允许的创建线程数量为 Integer.MAX_VALUE, 可能会创建大量的线程, 从而导致 OOM。
3) ScheduledThreadPool:允许的请求队列长度为 Integer.MAX_VALUE, 可能会堆积大量的请求, 从而导致 OOM。
CPU核数:可以通过 Runtime.getRuntime().availableProcessors() 获得
/**
*
* @param corePoolSize 核心线程数,默认情况下核心线程会一直存活,即使处于闲置状态也不会受存keepAliveTime限制。除非将allowCoreThreadTimeOut设置为true。CPU核数+1
* @param maximumPoolSize 线程池所能容纳的最大线程数。超过这个数的线程将被阻塞。当任务队列为没有设置大小的LinkedBlockingDeque时,这个值无效。 CPU核数*2+1
* @param keepAliveTime 非核心线程的闲置超时时间,超过这个时间就会被回收。
* @param unit 指定keepAliveTime的单位,如TimeUnit.SECONDS。当将allowCoreThreadTimeOut设置为true时对corePoolSize生效。
* @param workQueue 线程池中的任务队列.常用的有三种队列
* a.SynchronousQueue:是一种无缓冲的等待队列,在某次添加元素后必须等待其他线程取走后才能继续添加;
* b.LinkedBlockingDeque:是一个无界缓存的等待队列,不指定容量则为Integer最大值,锁是分离的;
* c.ArrayBlockingQueue:是一个有界缓存的等待队列,必须指定大小,锁是没有分离的;
* @param threadFactory 线程工厂,提供创建新线程的功能,通过线程工厂可以对线程的一些属性进行定制。
* @param handler 当线程池中的资源已经全部使用,添加新线程被拒绝时,会调用RejectedExecutionHandler的rejectedExecution方法,线程池有以下四种拒绝策略。
* a.AbortPolicy:当任务添加到线程池中被拒绝时,它将抛出RejectedExecutionException 异常。会有日志出来。正常可以用这个
* b.CallerRunsPolicy:当任务添加到线程池中被拒绝时,会在线程池当前正在运行的Thread线程池中run被拒绝的任务。 运行出来的进程名是 main
* c.DiscardOldestPolicy:当任务添加到线程池中被拒绝时,线程池会放弃等待队列中最旧的未处理任务(丢弃队列最前面的任务),然后将被拒绝的任务添加到等待队列中。
* d.DiscardPolicy:当任务添加到线程池中被拒绝时,线程池将丢弃被拒绝的任务。没有日志输出,系统统无感
*/
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler) {}

线程池状态含义:
RUNNING:接受新任务并且处理阻塞队列里的任务;
SHUTDOWN:拒绝新任务但是处理阻塞队列里的任务;
STOP:拒绝新任务并且抛弃阻塞队列里的任务同时会中断正在处理的任务;
TIDYING:所有任务都执行完(包含阻塞队列里面任务)当前线程池活动线程为 0,将要调用 terminated 方法
TERMINATED:终止状态。terminated 方法调用完成以后的状态;
线程池状态转换:
RUNNING -> SHUTDOWN:显式调用 shutdown() 方法,或者隐式调用了 finalize(),它里面调用了shutdown()方法。
RUNNING or SHUTDOWN)-> STOP:显式 shutdownNow() 方法;
SHUTDOWN -> TIDYING:当线程池和任务队列都为空的时候;
STOP -> TIDYING:当线程池为空的时候;
TIDYING -> TERMINATED:当 terminated() hook 方法执行完成时候;
线程池的监控:
通过线程池提供的参数进行监控。线程池里有一些属性在监控线程池的时候可以使用
getTaskCount:线程池已经执行的和未执行的任务总数;
getCompletedTaskCount:线程池已完成的任务数量,该值小于等于 taskCount;
getLargestPoolSize:线程池曾经创建过的最大线程数量。通过这个数据可以知道线程池是否满过,也就是达到了maximumPoolSize;
getPoolSize:线程池当前的线程数量;
getActiveCount:当前线程池中正在执行任务的线程数量。
做几个计算
corePoolSize = 每秒需要多少个线程处理?
threadcount = tasks/(1/taskcost) =tasks*taskcout = (100~1000)*0.1 = 10~100 个线程。corePoolSize设置应该大于10根据8020原则,如果80%的每秒任务数小于200,那么corePoolSize设置为20即可
queueCapacity = (coreSizePool/taskcost)*responsetime 计算可得 queueCapacity = 20/0.1*1 = 200。意思是队列里的线程可以等待1s,超过了的需要新开线程来执行切记不能设置为Integer.MAX_VALUE,这样队列会很大,线程数只会保持在corePoolSize大小,当任务陡增时,不能新开线程来执行,响应时间会随之陡增。
maxPoolSize = (max(tasks)- queueCapacity)/(1/taskcost) 计算可得 maxPoolSize = (1000-200)/10 = 80(最大任务数-队列容量)/每个线程每秒处理能力 = 最大线程数
rejectedExecutionHandler:根据具体情况来决定,任务不重要可丢弃,任务重要则要利用一些缓冲机制来处理
keepAliveTime和allowCoreThreadTimeout采用默认通常能满足
以上关于线程数量的计算并没有考虑CPU的情况。若结合CPU的情况,比如,当线程数量达到60时,CPU达到100%,则将maxPoolSize设置为80也不合适,此时若系统负载长时间维持在每秒1000个任务,则超出线程池处理能力,应设法降低每个任务的处理时间(taskcost)。
ThreadPoolExecutor 介绍的更多相关文章
- (转)java中Executor、ExecutorService、ThreadPoolExecutor介绍
转自: http://blog.csdn.net/linghu_java/article/details/17123057 ScheduledThreadPoolExecutor介绍: http:// ...
- ThreadPoolExecutor介绍
ThreadPoolExecutor的说明 ThreadPoolExecutor常见的操作主要有以下几个方法: getPoolSize():返回线程池实际的线程数. getActiveCount(): ...
- java线程池技术(二): 核心ThreadPoolExecutor介绍
版权声明:本文出自汪磊的博客,转载请务必注明出处. Java线程池技术属于比较"古老"而又比较基础的技术了,本篇博客主要作用是个人技术梳理,没什么新玩意. 一.Java线程池技术的 ...
- java中Executor、ExecutorService、ThreadPoolExecutor介绍(转)
1.Excutor 源码非常简单,只有一个execute(Runnable command)回调接口 public interface Executor { /** * Executes th ...
- java中Executor、ExecutorService、ThreadPoolExecutor介绍
源码非常简单,只有一个execute(Runnable command)回调接口 public interface Executor { /** * Executes the given c ...
- ThreadPoolExecutor解析
前言:在最新的阿里规范中强制使用ThreadPoolExecutor方式创建线程池,不允许使用Executors,因此有必要对ThreadPoolExecutor进行进一步了解. 1.ThreadPo ...
- Java并发编程总结5——ThreadPoolExecutor
一.ThreadPoolExecutor介绍 在jdk1.8中,构造函数有4个.以 ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, ...
- ThreadPoolExecutor线程池解析与BlockingQueue的三种实现
目的 主要介绍ThreadPoolExecutor的用法,和较浅显的认识,场景的使用方案等等,比较忙碌,如果有错误还请大家指出 ThreadPoolExecutor介绍 ThreadPoolExecu ...
- 多线程编程学习十一(ThreadPoolExecutor 详解).
一.ThreadPoolExecutor 参数说明 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keep ...
- Android的线程和线程池
---恢复内容开始--- 一.Android线程的形态 (一)AsyncTask解析 AysncTask简介:①.实现上封装了Thread和Handler ②.不适合进行特别耗时的后台任务 Ays ...
随机推荐
- Excel 使用 VLOOKUP 函数匹配特定列
前言 工作有一项内容,是根据新的表格的某一列的内容一对一匹配,生成一列新的表格.这就用到了 Excel 的 VLOOKUP 函数. 函数使用 函数体: =VLOOKUP(lookup_value,ta ...
- python函数str()避免类型错误
python中当输出需要拼接字符串(char)和整数(int)时,需要用到str()函数 如果编写如下代码: age = 23 print("Happy " + age +&quo ...
- Flutter搭建
目录 下载 Flutter SDK 配置 Flutter 环境变量及镜像 检查开发环境 参考 下载 Flutter SDK flutter官网下载:https://flutter.io/sdk-arc ...
- 面试题——为什么 Vue 中不要用 index 作为 key?(diff 算法详解)
前言 在vue中使用v-for时需要,都会提示或要求使用 :key,有的的开发者会直接使用数组的 index 作为 key 的值,但不建议直接使用 index作为 key 的值,有时我们面试时也会遇 ...
- 利用 Excel 对学生的成绩进行分析管理
利用 Excel 对学生的成绩进行分析和管理是一种常见且有效的方法.以下是一些步骤和技巧,以帮助您实施这一过程: 1. 数据输入:将学生成绩数据输入到 Excel 中的一个工作表中.每个学生可以有一行 ...
- [洛谷P8494] [IOI2022] 最罕见的昆虫
[IOI2022] 最罕见的昆虫 题目描述 Pak Blangkon 的房子四周有 \(N\) 只昆虫,编号为 \(0\) 至 \(N-1\).每只昆虫有一个类型,以从 \(0\) 至 \(10^9\ ...
- Maven仓库settings.xml配置信息
找到你的settings.xml配置文件E:\maven3.6.3\apache-maven-3.6.3\conf # 你的本地依赖仓库路径 <localRepository>E:\mav ...
- 【笔记整理】xpath复习
又是xpath.... 10年前学java就学过了...哈哈哈 要就看w3cschool的教程就行了, 函数部分会用得到: https://www.w3school.com.cn/xpath/xpat ...
- 可视化大屏与GIS之间如何实现互补?
在当今数字化时代,可视化大屏和地理信息系统(GIS)是两个在不同领域发挥重要作用的技术.可视化大屏以其生动.直观的图表.图像和动画展示方式,为数据可视化和信息展示提供了强大的工具.而GIS则通过地理空 ...
- 【scikit-learn基础】--『监督学习』之 LASSO回归
LASSO(Least Absolute Shrinkage and Selection Operator)回归模型一般都是用英文缩写表示,硬要翻译的话,可翻译为 最小绝对收缩和选择算子. 它是一种线 ...