本地写测试程序需要使用到多线程,就创建了一个线程池(参数没有深究,能保证测试程序运行就行),结果发现线程池并未按照预期创建多线程。

线程池相关代码如下:

测试代码如下:

运行结果如下,并未按照预期启动多线程,执行多个Runnable,而是阻塞在countDownLatch.await()的Runnable,而countDownRunnale并未执行:

查看了ThreadPoolExecutor的execute代码,发现使用线程池运行Runnable时,有三个分支:

1.如果核心线程都被占用(如第一个红框逻辑),走分支2

2.将Runnable加入到队列workQueue中(第二个红框),如果加入队列成功,不创建新的线程,等待已有线程运行。如果加入队列失败,走分支3

3.创建非核心线程去运行(第三个红框)

按照现在的测试现象,可以推测出countDownRunnale未运行的原因是被添加到队列中,而核心线程又一直被阻塞,导致测试程序无法正常运行。有两种修改方法可以尝试:

1.将LinkedBlockingQueue换成有限队列ArrayBlockingQueue(按照测试代码,可以将队列设置容量小于3)

2.将核心线程数扩大(只要保证核心线程不全部被阻塞即可)

经验证,上面两个方法都可以达到预期效果。

总结:线程池使用时,一定要考虑核心线程个数、最大线程个数以及缓冲队列容量。核心线程被占用完成后,任务会先尝试加到缓冲队列,如果加入缓冲队列成功,非核心线程不会被创建,缓冲队列中的任务只能等待核心线程结束上个任务后执行。如果缓冲队列太大,核心线程又都被阻塞,会影响后续任务的执行,影响效率甚至功能。

使用ThreadPoolExecutor遇到的核心线程被阻塞,非核心线程未按照预期运行问题相关推荐

  1. 【Java 并发编程】线程池机制 ( 线程池阻塞队列 | 线程池拒绝策略 | 使用 ThreadPoolExecutor 自定义线程池参数 )

    文章目录 一.线程池阻塞队列 二.拒绝策略 三.使用 ThreadPoolExecutor 自定义线程池参数 一.线程池阻塞队列 线程池阻塞队列是线程池创建的第 555 个参数 : BlockingQ ...

  2. idea debug只断点当前线程,不阻塞其他线程

    https://www.bilibili.com/video/BV1py4y1E7oA?p=60&spm_id_from=pageDriver

  3. 【Java 并发编程】线程池机制 ( 线程池执行任务细节分析 | 线程池执行 execute 源码分析 | 先创建核心线程 | 再放入阻塞队列 | 最后创建非核心线程 )

    文章目录 一.线程池执行任务细节分析 二.线程池执行 execute 源码分析 一.线程池执行任务细节分析 线程池执行细节分析 : 核心线程数 101010 , 最大小成熟 202020 , 非核心线 ...

  4. WM_TIMER消息在线程被阻塞时的系统处理

    我的脑海中忽然对这样一个问题有一些模糊,也就是当一个安装了定时器的线程被阻塞期间,定时器消息如何被送往消息队列?在线程从阻塞状态恢复以后,消息队列的状态是怎么样的?是否里面聚集多个WM_TIMER消息 ...

  5. 查看java线程堵塞排查_java线程阻塞问题排查

    我开发的worker,每隔几个月线上都会阻塞一次,一直都没查出问题.今天终于了了这个心结.把解决过程总结下和大家分享. 首先用jstack命令打出这个进程的全部线程堆栈.拿到线程dump文件之后,搜索 ...

  6. 【Android 异步操作】线程池 ( Worker 简介 | 线程池中的工作流程 runWorker | 从线程池任务队列中获取任务 getTask )

    文章目录 一.线程池中的 Worker ( 工作者 ) 二.线程池中的工作流程 runWorker 三.线程池任务队列中获取任务 getTask 在博客 [Android 异步操作]线程池 ( 线程池 ...

  7. 【Android 异步操作】线程池 ( 线程池简介 | 线程池初始化方法 | 线程池种类 | AsyncTask 使用线程池示例 )

    文章目录 一.线程池简介 二.线程池初始化方法简介 三.线程池使用示例 一.线程池简介 线程池一般是实现了 ExecutorService 接口的类 , 一般使用 ThreadPoolExecutor ...

  8. 【Android 异步操作】线程池 ( 线程池作用 | 线程池种类 | 线程池工作机制 | 线程池任务调度源码解析 )

    文章目录 一.线程池作用 二.线程池种类 三.线程池工作机制 四.线程池任务调度源码解析 一.线程池作用 线程池作用 : ① 避免创建线程 : 避免每次使用线程时 , 都需要 创建线程对象 ; ② 统 ...

  9. java 线程 状态 图_Java线程中的生命周期和状态控制图文详解

    这篇文章主要介绍了Java线程的生命周期和状态控制,需要的朋友可以参考下 一.线程的生命周期 线程状态转换图: 1.新建状态 用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于 ...

最新文章

  1. 你还在等着用户反馈BUG?
  2. python3 requests 不进行编码 直接发送的方法
  3. Windows 95 诞生 25 周年
  4. JavaScript 事件入门知识
  5. Python基本数据类型之整型
  6. .NET简谈组件程序设计之(上下文与同步域)
  7. vmware使用已有linux系统的物理磁盘分区
  8. HTML5+CSS3 Pink老师课后作业——小米logo过渡切换的实现
  9. Excel如何快速对比数据
  10. Reactor(反应器)模式
  11. Cabbage教学(3)——数学计算和文件操作
  12. 西部数据绿盘、蓝盘、黑盘、红盘和紫盘有什么区别
  13. 阿里云盘下载与公测预约(最新)
  14. Canvas学习:绘制箭头
  15. 网络推广和网络营销的区别
  16. ospf协议基本概念
  17. 为什么group by后面不能使用列的别名
  18. 【笔记】曝光值EV曝光补偿曝光量
  19. 微信订阅号之客服消息接口回复
  20. 利用系统方法分析COBIT5解决问题的原理

热门文章

  1. Android开发艺术探讨精华(完结)
  2. 我的目标,我的梦想,我的坚持---给自己一个见证
  3. OI (信息 ) 竞赛中的对拍程序,造数据,对拍利器
  4. 模拟(持续更新、整理)
  5. 2021-06-08 imshow函数不显示图像解决办法
  6. matlab 基础函数 floor、conv、histeq、im2bw
  7. python 转义符与转义字符 200310
  8. jsp页面更换图片后,还是显示原来的图片解决方法!
  9. 传说中的格林达姆同人图像合集(别名为[绿bar娘]或[greendam]等等)
  10. 漫画 | 大数据开发有多难?