ThreadPoolExecutor执行过程分析
ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler)
- corePoolSize:线程池核心线程数(平时保留的线程数)
- maximumPoolSize:线程池最大线程数(当workQueue都放不下时,启动新线程,最大线程数)
- keepAliveTime:超出corePoolSize数量的线程的保留时间。
- unit:keepAliveTime单位
workQueue:阻塞队列,存放来不及执行的线程
- ArrayBlockingQueue:构造函数一定要传大小
- LinkedBlockingQueue:构造函数不传大小会默认为65536(Integer.MAX_VALUE ),当大量请求任务时,容易造成 内存耗尽。
- SynchronousQueue:同步队列,一个没有存储空间的阻塞队列 ,将任务同步交付给工作线程。
- PriorityBlockingQueue : 优先队列
- threadFactory:线程工厂
handler:饱和策略
- AbortPolicy(默认):直接抛弃
- CallerRunsPolicy:用调用者的线程执行任务
- DiscardOldestPolicy:抛弃队列中最久的任务
- DiscardPolicy:抛弃当前任务
ThreadPoolExecutor 测试代码
//test.java
volatile int finishState = 0;@Test
public void test4() throws InterruptedException, ExecutionException { ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3, 7, 10, TimeUnit.SECONDS, new LinkedBlockingDeque<>(10)); ExecutorCompletionService<String> executorCompletionService = new ExecutorCompletionService(threadPoolExecutor); Runnable runnable = new Runnable() { @Override public void run() { for (int i = 0; i < 50; i++) { String name = "name_" + i; TestCallable testCallable = new TestCallable(name); try { executorCompletionService.submit(testCallable); synchronized (lock) { System.out.print("+++添加任务 name: " + name); System.out.print(" ActiveCount: " + threadPoolExecutor.getActiveCount()); System.out.print(" poolSize: " + threadPoolExecutor.getPoolSize()); System.out.print(" queueSize: " + threadPoolExecutor.getQueue().size()); System.out.println(" taskCount: " + threadPoolExecutor.getTaskCount()); } } catch (RejectedExecutionException e) { synchronized (lock) { System.out.println("拒绝:" + name); } } try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } } finishState = 1; } }; Thread addThread = new Thread(runnable); addThread.start(); //System.out.println(" taskCount: " + threadPoolExecutor.getTaskCount()); //添加的任务有被抛弃的。taskCount不一定等于添加的任务。 int completeCount = 0; while (!(completeCount == threadPoolExecutor.getTaskCount() && finishState == 1)) { Future<String> take = executorCompletionService.take(); String taskName = take.get(); synchronized (lock) { System.out.print("---完成任务 name: " + taskName); System.out.print(" ActiveCount: " + threadPoolExecutor.getActiveCount()); System.out.print(" poolSize: " + threadPoolExecutor.getPoolSize()); System.out.print(" queueSize: " + threadPoolExecutor.getQueue().size()); System.out.print(" taskCount: " + threadPoolExecutor.getTaskCount()); System.out.println(" finishTask:" + (++completeCount)); } } addThread.join(); while (threadPoolExecutor.getPoolSize() > 0) { Thread.sleep(1000); synchronized (lock) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss"); System.out.print(simpleDateFormat.format(new Date())); //System.out.print("name: " + taskName); System.out.print(" ActiveCount: " + threadPoolExecutor.getActiveCount()); System.out.print(" poolSize: " + threadPoolExecutor.getPoolSize()); System.out.print(" queueSize: " + threadPoolExecutor.getQueue().size()); System.out.println(" taskCount: " + threadPoolExecutor.getTaskCount()); } } // Tell threads to finish off. threadPoolExecutor.shutdown(); // Wait for everything to finish. while (!threadPoolExecutor.awaitTermination(10, TimeUnit.SECONDS)) { System.out.println("complete"); } }
//TestCallable.java
public class TestCallable implements Callable<String>{ private String name; public TestCallable(String name) { this.name = name; } @Override public String call() throws Exception { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } return this.name; } }
执行结果
+++添加任务 name: name_0 ActiveCount: 1 poolSize: 1 queueSize: 0 taskCount: 1 +++添加任务 name: name_1 ActiveCount: 2 poolSize: 2 queueSize: 0 taskCount: 2 +++添加任务 name: name_2 ActiveCount: 3 poolSize: 3 queueSize: 0 taskCount: 3 //corePoolSize=3,所以poolSize逐渐加到3. +++添加任务 name: name_3 ActiveCount: 3 poolSize: 3 queueSize: 1 taskCount: 4 +++添加任务 name: name_4 ActiveCount: 3 poolSize: 3 queueSize: 2 taskCount: 5 +++添加任务 name: name_5 ActiveCount: 3 poolSize: 3 queueSize: 3 taskCount: 6 +++添加任务 name: name_6 ActiveCount: 3 poolSize: 3 queueSize: 4 taskCount: 7 +++添加任务 name: name_7 ActiveCount: 3 poolSize: 3 queueSize: 5 taskCount: 8 +++添加任务 name: name_8 ActiveCount: 3 poolSize: 3 queueSize: 6 taskCount: 9 +++添加任务 name: name_9 ActiveCount: 3 poolSize: 3 queueSize: 7 taskCount: 10 ---完成任务 name: name_0 ActiveCount: 3 poolSize: 3 queueSize: 6 taskCount: 10 finishTask:1 +++添加任务 name: name_10 ActiveCount: 3 poolSize: 3 queueSize: 7 taskCount: 11 ---完成任务 name: name_1 ActiveCount: 3 poolSize: 3 queueSize: 6 taskCount: 11 finishTask:2 +++添加任务 name: name_11 ActiveCount: 3 poolSize: 3 queueSize: 7 taskCount: 12 ---完成任务 name: name_2 ActiveCount: 3 poolSize: 3 queueSize: 6 taskCount: 12 finishTask:3 +++添加任务 name: name_12 ActiveCount: 3 poolSize: 3 queueSize: 7 taskCount: 13 +++添加任务 name: name_13 ActiveCount: 3 poolSize: 3 queueSize: 8 taskCount: 14 +++添加任务 name: name_14 ActiveCount: 3 poolSize: 3 queueSize: 9 taskCount: 15 +++添加任务 name: name_15 ActiveCount: 3 poolSize: 3 queueSize: 10 taskCount: 16 //因为任务队列为:new LinkedBlockingDeque<>(10),core线程不够用时,将任务添加到队列中。 //queueSize到10,队列已满。开始增加poolSize,加到maximumPoolSize=7 +++添加任务 name: name_16 ActiveCount: 4 poolSize: 4 queueSize: 10 taskCount: 17 +++添加任务 name: name_17 ActiveCount: 5 poolSize: 5 queueSize: 10 taskCount: 18 +++添加任务 name: name_18 ActiveCount: 6 poolSize: 6 queueSize: 10 taskCount: 19 +++添加任务 name: name_19 ActiveCount: 7 poolSize: 7 queueSize: 10 taskCount: 20 ---完成任务 name: name_3 ActiveCount: 7 poolSize: 7 queueSize: 9 taskCount: 20 finishTask:4 +++添加任务 name: name_20 ActiveCount: 7 poolSize: 7 queueSize: 10 taskCount: 21 ---完成任务 name: name_4 ActiveCount: 7 poolSize: 7 queueSize: 9 taskCount: 21 finishTask:5 +++添加任务 name: name_21 ActiveCount: 7 poolSize: 7 queueSize: 10 taskCount: 22 ---完成任务 name: name_5 ActiveCount: 7 poolSize: 7 queueSize: 9 taskCount: 22 finishTask:6 +++添加任务 name: name_22 ActiveCount: 7 poolSize: 7 queueSize: 10 taskCount: 23 //poolSize=maximumPoolSize,queueSize=10,都满了。执行饱和策略。默认AbortPolicy抛弃新任务。 拒绝:name_23 拒绝:name_24 拒绝:name_25 ---完成任务 name: name_16 ActiveCount: 7 poolSize: 7 queueSize: 10 taskCount: 23 finishTask:7 +++添加任务 name: name_26 ActiveCount: 7 poolSize: 7 queueSize: 10 taskCount: 24 ---完成任务 name: name_17 ActiveCount: 7 poolSize: 7 queueSize: 9 taskCount: 24 finishTask:8 +++添加任务 name: name_27 ActiveCount: 7 poolSize: 7 queueSize: 10 taskCount: 25 ---完成任务 name: name_18 ActiveCount: 7 poolSize: 7 queueSize: 9 taskCount: 25 finishTask:9 +++添加任务 name: name_28 ActiveCount: 7 poolSize: 7 queueSize: 10 taskCount: 26 ---完成任务 name: name_19 ActiveCount: 7 poolSize: 7 queueSize: 9 taskCount: 26 finishTask:10 +++添加任务 name: name_29 ActiveCount: 7 poolSize: 7 queueSize: 10 taskCount: 27 ---完成任务 name: name_6 ActiveCount: 7 poolSize: 7 queueSize: 9 taskCount: 27 finishTask:11 +++添加任务 name: name_30 ActiveCount: 7 poolSize: 7 queueSize: 10 taskCount: 28 ---完成任务 name: name_7 ActiveCount: 7 poolSize: 7 queueSize: 9 taskCount: 28 finishTask:12 +++添加任务 name: name_31 ActiveCount: 7 poolSize: 7 queueSize: 10 taskCount: 29 ---完成任务 name: name_8 ActiveCount: 7 poolSize: 7 queueSize: 9 taskCount: 29 finishTask:13 +++添加任务 name: name_32 ActiveCount: 7 poolSize: 7 queueSize: 10 taskCount: 30 拒绝:name_33 拒绝:name_34 拒绝:name_35 ---完成任务 name: name_9 ActiveCount: 7 poolSize: 7 queueSize: 9 taskCount: 30 finishTask:14 +++添加任务 name: name_36 ActiveCount: 7 poolSize: 7 queueSize: 10 taskCount: 31 ---完成任务 name: name_10 ActiveCount: 7 poolSize: 7 queueSize: 9 taskCount: 31 finishTask:15 +++添加任务 name: name_37 ActiveCount: 7 poolSize: 7 queueSize: 10 taskCount: 32 ---完成任务 name: name_11 ActiveCount: 7 poolSize: 7 queueSize: 9 taskCount: 32 finishTask:16 +++添加任务 name: name_38 ActiveCount: 7 poolSize: 7 queueSize: 10 taskCount: 33 ---完成任务 name: name_12 ActiveCount: 7 poolSize: 7 queueSize: 9 taskCount: 33 finishTask:17 +++添加任务 name: name_39 ActiveCount: 7 poolSize: 7 queueSize: 10 taskCount: 34 ---完成任务 name: name_13 ActiveCount: 7 poolSize: 7 queueSize: 9 taskCount: 34 finishTask:18 +++添加任务 name: name_40 ActiveCount: 7 poolSize: 7 queueSize: 10 taskCount: 35 ---完成任务 name: name_14 ActiveCount: 7 poolSize: 7 queueSize: 9 taskCount: 35 finishTask:19 +++添加任务 name: name_41 ActiveCount: 7 poolSize: 7 queueSize: 10 taskCount: 36 ---完成任务 name: name_15 ActiveCount: 7 poolSize: 7 queueSize: 9 taskCount: 36 finishTask:20 +++添加任务 name: name_42 ActiveCount: 7 poolSize: 7 queueSize: 10 taskCount: 37 拒绝:name_43 拒绝:name_44 拒绝:name_45 ---完成任务 name: name_20 ActiveCount: 7 poolSize: 7 queueSize: 9 taskCount: 37 finishTask:21 +++添加任务 name: name_46 ActiveCount: 7 poolSize: 7 queueSize: 10 taskCount: 38 ---完成任务 name: name_21 ActiveCount: 7 poolSize: 7 queueSize: 9 taskCount: 38 finishTask:22 +++添加任务 name: name_47 ActiveCount: 7 poolSize: 7 queueSize: 10 taskCount: 39 ---完成任务 name: name_22 ActiveCount: 7 poolSize: 7 queueSize: 9 taskCount: 39 finishTask:23 //消费速度大于添加速度,poolSize并不减少,先把queue中的任务逐一执行完成。 +++添加任务 name: name_48 ActiveCount: 7 poolSize: 7 queueSize: 10 taskCount: 40 ---完成任务 name: name_26 ActiveCount: 7 poolSize: 7 queueSize: 9 taskCount: 40 finishTask:24 ---完成任务 name: name_27 ActiveCount: 7 poolSize: 7 queueSize: 8 taskCount: 40 finishTask:25 +++添加任务 name: name_49 ActiveCount: 7 poolSize: 7 queueSize: 9 taskCount: 41 ---完成任务 name: name_28 ActiveCount: 7 poolSize: 7 queueSize: 8 taskCount: 41 finishTask:26 ---完成任务 name: name_29 ActiveCount: 7 poolSize: 7 queueSize: 7 taskCount: 41 finishTask:27 ---完成任务 name: name_30 ActiveCount: 7 poolSize: 7 queueSize: 6 taskCount: 41 finishTask:28 ---完成任务 name: name_31 ActiveCount: 7 poolSize: 7 queueSize: 5 taskCount: 41 finishTask:29 ---完成任务 name: name_32 ActiveCount: 7 poolSize: 7 queueSize: 4 taskCount: 41 finishTask:30 ---完成任务 name: name_36 ActiveCount: 7 poolSize: 7 queueSize: 3 taskCount: 41 finishTask:31 ---完成任务 name: name_37 ActiveCount: 7 poolSize: 7 queueSize: 2 taskCount: 41 finishTask:32 ---完成任务 name: name_38 ActiveCount: 7 poolSize: 7 queueSize: 1 taskCount: 41 finishTask:33 ---完成任务 name: name_39 ActiveCount: 7 poolSize: 7 queueSize: 0 taskCount: 41 finishTask:34 //ActiveCount开始减少。 ---完成任务 name: name_40 ActiveCount: 6 poolSize: 7 queueSize: 0 taskCount: 41 finishTask:35 ---完成任务 name: name_41 ActiveCount: 5 poolSize: 7 queueSize: 0 taskCount: 41 finishTask:36 ---完成任务 name: name_42 ActiveCount: 4 poolSize: 7 queueSize: 0 taskCount: 41 finishTask:37 ---完成任务 name: name_46 ActiveCount: 3 poolSize: 7 queueSize: 0 taskCount: 41 finishTask:38 ---完成任务 name: name_47 ActiveCount: 2 poolSize: 7 queueSize: 0 taskCount: 41 finishTask:39 ---完成任务 name: name_48 ActiveCount: 1 poolSize: 7 queueSize: 0 taskCount: 41 finishTask:40 ---完成任务 name: name_49 ActiveCount: 0 poolSize: 7 queueSize: 0 taskCount: 41 finishTask:41 22:47:49 ActiveCount: 0 poolSize: 7 queueSize: 0 taskCount: 41 22:47:50 ActiveCount: 0 poolSize: 7 queueSize: 0 taskCount: 41 22:47:51 ActiveCount: 0 poolSize: 7 queueSize: 0 taskCount: 41 22:47:52 ActiveCount: 0 poolSize: 7 queueSize: 0 taskCount: 41 22:47:53 ActiveCount: 0 poolSize: 7 queueSize: 0 taskCount: 41 22:47:54 ActiveCount: 0 poolSize: 7 queueSize: 0 taskCount: 41 22:47:55 ActiveCount: 0 poolSize: 7 queueSize: 0 taskCount: 41 22:47:56 ActiveCount: 0 poolSize: 7 queueSize: 0 taskCount: 41 22:47:57 ActiveCount: 0 poolSize: 5 queueSize: 0 taskCount: 41 //由于keepAliveTime=10,大概10s后poolSize恢复为corePoolSize。 22:47:58 ActiveCount: 0 poolSize: 3 queueSize: 0 taskCount: 41 22:47:59 ActiveCount: 0 poolSize: 3 queueSize: 0 taskCount: 41 22:48:00 ActiveCount: 0 poolSize: 3 queueSize: 0 taskCount: 41
注意
《阿里巴巴java开发手册》
线程池不使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样 的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
说明: Executors 返回的线程池对象的弊端如下:
- FixedThreadPool 和 SingleThreadPool : 允许的请求队列长度为 Integer.MAX_VALUE ,可能会堆积大量的请求,从而导致 OOM 。
- CachedThreadPool 和 ScheduledThreadPool : 允许的创建线程数量为 Integer.MAX_VALUE ,可能会创建大量的线程,从而导致 OOM 。
Reference
- 深入浅出Java线程池
转载于:https://www.cnblogs.com/sessionbest/p/9396706.html
ThreadPoolExecutor执行过程分析相关推荐
- Ansible执行过程分析、异步模式和速度优化
Ansible系列(七):执行过程分析.异步模式和速度优化 分类: Linux服务篇 undefined 我写了更完善的Ansible专栏文章:一步到位玩儿透Ansible Ansible系列文章:h ...
- ThreadPoolExecutor执行任务,异常日志缺失问题
ThreadPoolExecutor执行任务,异常日志缺失问题 参考文章: (1)ThreadPoolExecutor执行任务,异常日志缺失问题 (2)https://www.cnblogs.com/ ...
- 4. 系统调用执行过程分析
##################################### 作者:张卓 原创作品转载请注明出处:<Linux操作系统分析>MOOC课程 http://www.xuetang ...
- ART运行时Semi-Space(SS)和Generational Semi-Space(GSS)GC执行过程分析
Semi-Space(SS)GC和Generational Semi-Space(GSS)GC是ART运行时引进的两个Compacting GC.它们的共同特点是都具有一个From Space和一个T ...
- 【转】2.2【MySQL】运行原理(二):InnoDB 内存结构、磁盘结构及update sql执行过程分析
前一篇讲完了查询流程,我们是不是再讲讲更新流程.插入流程和删除流程?在数据库里面,我们说的update操作其实包括了更新.插入和删除.如果大家有看过MyBatis的源码,应该知道Executor里面也 ...
- Chromium硬件加速渲染的OpenGL命令执行过程分析
在Chromium中,由于GPU进程的存在,WebGL端.Render端和Browser端的GPU命令是代理给GPU进程执行的.Chromium将它们要执行的GPU命令进行编码,然后写入到一个命令缓冲 ...
- tiny-cnn执行过程分析(MNIST)
在http://blog.csdn.net/fengbingchun/article/details/50573841中以MNIST为例对tiny-cnn的使用进行了介绍,下面对其执行过程进行分析: ...
- php的foreach循环执行过程分析以及循环中执行unset()的一些问题
文章目录 一.前言 二.foreach的执行过程 1.关于版本不同的foreach变化 2.关于引用计数 3.探寻foreach的运行过程 三.foreach中执行unset()的问题 1.当我们是为 ...
- MDK_main()代码执行过程分析
1.1 __main()代码执行分析 以keyled程序为例说明,keyled代码请参考我的博客网址:http://my.csdn.net/wfq0624/code/detail/7645 程 ...
最新文章
- linux内核链表使用例,linux内核链表的使用例子
- 【博士论文】分形计算系统
- 怎么在线安装php文件,PHP在线安装数据库
- nagios视频教程【原创】
- 没有任何基础的可以学python吗-对没有编程基础的人来说,直接学Python入门IT合适吗?...
- mysql uuid 性能_mysql InnoDB UUID 主键 性能优化【性能分析篇】.md
- 论文笔记 OHEM: Training Region-based Object Detectors with Online Hard Example Mining
- 【C语言笔记】指定初始化器
- 一文讲透 Serverless Kubernetes 容器服务
- G950U破解电信4G正确姿势
- html实心圆点特殊符号,和平精英名称添加圆点符号的方法 和平精英圆点符号代码分享...
- 机器人编程学的是什么
- matlab中figure图片大小修改
- Python3处理HTTP请求
- GTC2019大会的部分总结
- 计算机win10内存,win10系统电脑可用内存异常的解决方法
- 莫拉克电梯服务器说明书_默纳克操作手册
- RTT开发之windows 环境配置
- XML学习笔记(1)
- 带nfc 的 android 华为,目前支持NFC的手机这么多,为什么只有小米华为能覆盖这么多城市...
热门文章
- MongoDB中的分页–如何真正避免性能下降?
- 谷歌正在移除 Chrome 的“关闭其他选项卡”选项
- protobuf3 自定义option_Protobuf3语法详解
- linux日志搜索关键词_linux中的实用技巧和快捷键总结
- JS中Promise函数then的奥秘探究
- java xml特殊字符转义_Java中将xml文件转化为json遇到特殊字符会报错!
- oracle库创建2个监听,Oracle 添加第二个实例 和 监听
- mysql快捷键设置_MySQL快捷命令
- zklib php,php 安装zookeeper扩展报错
- java sql 写入万条数据_如何快速向数据库插1000万数据?4种方法对比,它简单却速度最快