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 ...
随机推荐
- SpringBoot系列之MyBatis Plus自动填充实现
系列博客专栏:SpringBoot2.0系列博客专栏 开发环境 JDK 1.8 SpringBoot2.2.1 Maven 3.2+ Mysql5.7.36 开发工具 IntelliJ IDEA sm ...
- Android app的暗黑模式适配实现
原文地址: Android app的暗黑模式适配实现 - Stars-One的杂货小窝 很久之前放在草稿箱的一篇简单笔记,是之前蓝奏云批量下载工具Android版本实现暗黑主题的适配记录 本文所说的这 ...
- Android 锁屏时的生命周期
锁定屏幕前,应用被打开:onCreate->onStart->onResume 此时按下电源键,锁定屏幕:onPause->onStop 解锁屏幕,重新回到应用:onRestart- ...
- Kubernetes Gateway API 攻略:解锁集群流量服务新维度!
Kubernetes Gateway API 刚刚 GA,旨在改进将集群服务暴露给外部的过程.这其中包括一套更标准.更强大的 API资源,用于管理已暴露的服务.在这篇文章中,我将介绍 Gateway ...
- 在路上---学习篇(一)Python 数据结构和算法 (6)基于GA(遗传)算法的小案例
独白 最近了解到一种算法叫遗传算法,对其比较感兴趣,研究了一下,是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法.遗传算法是从代表问题可 ...
- Android 实现APP可切换多语言
原文: Android 实现APP可切换多语言 - Stars-One的杂货小窝 如果是单独给app加上国际化,其实很容易,创建对应的国家资源文件夹即可,如values-en,values-pt,ap ...
- BI工具:让数据分析井然有序一望而知
BI(Business Intelligence)工具是一类专门用于数据分析和决策支持的软件工具. 它们能够将企业内部和外部的数据进行整合.处理和可视化,帮助用户从海量数据中获取有价值的见解和洞察,并 ...
- springboot操作nosql的mongodb,或者是如何在mongodb官网创建服务器并进行操作
第一步:在mongodb的官网里面创建云服务器 点进去 这是免费的,由于是一个项目只可以创建一个,这里我已经创建好了 用本地的mongodb服务也是可以的 第二步:点击connect,下载连接mong ...
- MySQL笔记01: MySQL入门_1.1 MySQL概述
1.1 MySQL概述 MySQL是一个关系数据库管理系统(Relational DataBase Management System,RDBMS).它是一个程序,可以存储大量的种类繁多的数据,并且提 ...
- C# 从代码入门 Mysql 数据库事务
目录 生成数据库数据 Mysql 数据库事务基础 数据库的并发一致性问题 数据库事务的隔离级别 BeginTransaction() 和 TransactionScope 的区别 BeginTrans ...