一次触发线程池拒绝策略问题的排查

一次触发线程池拒绝策略问题的排查

这个问题的原因是团队中的同事排查出来的,本人觉得这个问题很经典,所以记录一下

线上偶尔会出现线程池拒绝策略触发的告警

每次出现告警都会查看数据库、JVM等监控,系统都是比较平稳的,没有出现请求暴涨的情况,所以认为大概率是线程池配置的问题

分析过程

线程池参数有很多,但最核心的是三个corePoolSize、maximumPoolSize、workQueuequeueCapacity,三者的关系如下

系统通过JDK原生线程池ThreadPoolTaskExecutor设置线程池参数,细细看了这个类的代码,corePoolSize、maxPoolSize、keepAliveSeconds等参数都是正常的设置(set),只有queueCapacity参数做了一些判断,代码如下

如果阻塞队列容量大于0,阻塞队列使用LinkedBlockingQueue,等于0,使用SynchronousQueue

于是做个测试,看看是不是这里导致的

测试代码如下,如果触发了线程池拒绝策略,打印出来

理论上核心线程数有10个,一组执行完,另一组还可以使用核心线程执行,是不需要触发非核心线程的,结果出乎我的意料

queueCapacity等于1的情况

queueCapacity等于0的情况

显然,使用LinkedBlockingQueue,线程复用率不高,导致触发了线程池拒绝策略

那么问题来了,为什么LinkedBlockingQueue线程复用率不高,google搜索了一下

千篇一律都是这种类型的文章,只有结论,没有说为什么,所以只能去看源码

线程池源码

线程池提交任务的代码如下

这段代码跟文章开头那张图是完美对应的,核心代码在于 workQueue.offer(command),因为入队失败,才会 addWorker(command, false)创建非核心线程

所以为什么SynchronousQueue会入队成功,LinkedBlockingQueue会入队失败,只能看两个队列的源码,比较一下,下面简单说说两者的源码

SynchronousQueue源码

SynchronousQueue代码还是蛮复杂的,有公平非公平两种模式,默认是非公平,如下图

  1. SynchronousQueue每个节点有三个状态,分别是未匹配的消费者、未匹配的生产者、正在匹配另一个生产者或消费者
  2. 当队列为空时,生产者或者消费者会直接进入栈中,自旋或者阻塞等待生产者或者消费者匹配
  3. 当栈中有生产者,消费者进入会去匹配该生产者,或者当栈中有消费者,生产者进入会进行匹配,匹配完成一起出栈
  4. 当栈中有生产者与消费者正在匹配,又进来了一个生产者或者消费者线程,它会协助两者匹配

看上是不是很懵,其实我一开始也很懵,juc包的代码是很难理解的,下面是详细的代码

LinkedBlockingQueue 源码解析

我的一点猜想

  1. LinkedBlockingQueue存取节点使用锁进行了互斥,性能没有SynchronousQueue好,所以同样的数据SynchronousQueue处理起来更快
  2. SynchronousQueue支持多线程协作栈中数据,可以充分利用多线程的好处,不像LinkedBlockingQueue,队列到达上限,直接返回false,任务只能创建非核心线程

由于本人水平有限,无法在多线程的环境下验证自己的猜想,期待大佬指点一二

参考文档

tech.meituan.com/2020/04/02/...

相关推荐
专注API从业者41 分钟前
Open Claw 京东商品监控选品实战:一键抓取、实时监控、高效选品
java·服务器·数据库
摇滚侠1 小时前
DBeaver 导入数据库 导入 SQL 文件 MySQL 备份恢复
java·数据库·mysql
keep one's resolveY1 小时前
SpringBoot实现重试机制的四种方案
java·spring boot·后端
天空属于哈夫克32 小时前
企业微信API常见的错误和解决方案
java·数据库·企业微信
摇滚侠3 小时前
VMvare 虚拟机 Oracle19c 安装步骤,远程连接 Oracle19c,百度网盘安装包
java·oracle
梁萌3 小时前
idea报错找不到XX包的解决方法
java·intellij-idea·启动报错·缺少包
女生也可以敲代码3 小时前
AI时代下的50道前端开发面试题:从基础到大模型应用
前端·面试
Agent产品评测局3 小时前
生产排期与MES/ERP系统打通,实操方法详解 —— 2026企业级智能体自动化选型与实战指南
java·运维·人工智能·ai·chatgpt·自动化
阿丰资源3 小时前
基于Spring Boot的电影城管理系统(直接运行)
java·spring boot·后端
呱牛do it3 小时前
企业级门户网站设计与实现:基于SpringBoot + Vue3的全栈解决方案(Day 8)
java