使用ThreadPoolExecutor遇到的核心线程被阻塞,非核心线程未按照预期运行问题
本地写测试程序需要使用到多线程,就创建了一个线程池(参数没有深究,能保证测试程序运行就行),结果发现线程池并未按照预期创建多线程。
线程池相关代码如下:
测试代码如下:
运行结果如下,并未按照预期启动多线程,执行多个Runnable,而是阻塞在countDownLatch.await()的Runnable,而countDownRunnale并未执行:
查看了ThreadPoolExecutor的execute代码,发现使用线程池运行Runnable时,有三个分支:
1.如果核心线程都被占用(如第一个红框逻辑),走分支2
2.将Runnable加入到队列workQueue中(第二个红框),如果加入队列成功,不创建新的线程,等待已有线程运行。如果加入队列失败,走分支3
3.创建非核心线程去运行(第三个红框)
按照现在的测试现象,可以推测出countDownRunnale未运行的原因是被添加到队列中,而核心线程又一直被阻塞,导致测试程序无法正常运行。有两种修改方法可以尝试:
1.将LinkedBlockingQueue换成有限队列ArrayBlockingQueue(按照测试代码,可以将队列设置容量小于3)
2.将核心线程数扩大(只要保证核心线程不全部被阻塞即可)
经验证,上面两个方法都可以达到预期效果。
总结:线程池使用时,一定要考虑核心线程个数、最大线程个数以及缓冲队列容量。核心线程被占用完成后,任务会先尝试加到缓冲队列,如果加入缓冲队列成功,非核心线程不会被创建,缓冲队列中的任务只能等待核心线程结束上个任务后执行。如果缓冲队列太大,核心线程又都被阻塞,会影响后续任务的执行,影响效率甚至功能。
使用ThreadPoolExecutor遇到的核心线程被阻塞,非核心线程未按照预期运行问题相关推荐
- 【Java 并发编程】线程池机制 ( 线程池阻塞队列 | 线程池拒绝策略 | 使用 ThreadPoolExecutor 自定义线程池参数 )
文章目录 一.线程池阻塞队列 二.拒绝策略 三.使用 ThreadPoolExecutor 自定义线程池参数 一.线程池阻塞队列 线程池阻塞队列是线程池创建的第 555 个参数 : BlockingQ ...
- idea debug只断点当前线程,不阻塞其他线程
https://www.bilibili.com/video/BV1py4y1E7oA?p=60&spm_id_from=pageDriver
- 【Java 并发编程】线程池机制 ( 线程池执行任务细节分析 | 线程池执行 execute 源码分析 | 先创建核心线程 | 再放入阻塞队列 | 最后创建非核心线程 )
文章目录 一.线程池执行任务细节分析 二.线程池执行 execute 源码分析 一.线程池执行任务细节分析 线程池执行细节分析 : 核心线程数 101010 , 最大小成熟 202020 , 非核心线 ...
- WM_TIMER消息在线程被阻塞时的系统处理
我的脑海中忽然对这样一个问题有一些模糊,也就是当一个安装了定时器的线程被阻塞期间,定时器消息如何被送往消息队列?在线程从阻塞状态恢复以后,消息队列的状态是怎么样的?是否里面聚集多个WM_TIMER消息 ...
- 查看java线程堵塞排查_java线程阻塞问题排查
我开发的worker,每隔几个月线上都会阻塞一次,一直都没查出问题.今天终于了了这个心结.把解决过程总结下和大家分享. 首先用jstack命令打出这个进程的全部线程堆栈.拿到线程dump文件之后,搜索 ...
- 【Android 异步操作】线程池 ( Worker 简介 | 线程池中的工作流程 runWorker | 从线程池任务队列中获取任务 getTask )
文章目录 一.线程池中的 Worker ( 工作者 ) 二.线程池中的工作流程 runWorker 三.线程池任务队列中获取任务 getTask 在博客 [Android 异步操作]线程池 ( 线程池 ...
- 【Android 异步操作】线程池 ( 线程池简介 | 线程池初始化方法 | 线程池种类 | AsyncTask 使用线程池示例 )
文章目录 一.线程池简介 二.线程池初始化方法简介 三.线程池使用示例 一.线程池简介 线程池一般是实现了 ExecutorService 接口的类 , 一般使用 ThreadPoolExecutor ...
- 【Android 异步操作】线程池 ( 线程池作用 | 线程池种类 | 线程池工作机制 | 线程池任务调度源码解析 )
文章目录 一.线程池作用 二.线程池种类 三.线程池工作机制 四.线程池任务调度源码解析 一.线程池作用 线程池作用 : ① 避免创建线程 : 避免每次使用线程时 , 都需要 创建线程对象 ; ② 统 ...
- java 线程 状态 图_Java线程中的生命周期和状态控制图文详解
这篇文章主要介绍了Java线程的生命周期和状态控制,需要的朋友可以参考下 一.线程的生命周期 线程状态转换图: 1.新建状态 用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于 ...
最新文章
- 你还在等着用户反馈BUG?
- python3 requests 不进行编码 直接发送的方法
- Windows 95 诞生 25 周年
- JavaScript 事件入门知识
- Python基本数据类型之整型
- .NET简谈组件程序设计之(上下文与同步域)
- vmware使用已有linux系统的物理磁盘分区
- HTML5+CSS3 Pink老师课后作业——小米logo过渡切换的实现
- Excel如何快速对比数据
- Reactor(反应器)模式
- Cabbage教学(3)——数学计算和文件操作
- 西部数据绿盘、蓝盘、黑盘、红盘和紫盘有什么区别
- 阿里云盘下载与公测预约(最新)
- Canvas学习:绘制箭头
- 网络推广和网络营销的区别
- ospf协议基本概念
- 为什么group by后面不能使用列的别名
- 【笔记】曝光值EV曝光补偿曝光量
- 微信订阅号之客服消息接口回复
- 利用系统方法分析COBIT5解决问题的原理