线程池嵌套导致的死锁问题

1、背景

有一个报告功能,报告需要生成1个word,6个excel附件,总共7个文件,需要记录报告生成进度,进度字段jd初始化是0,每个文件生成成功进度加1,生成失败就把生成状态置为失败。

更新进度语句:update bg set jd = jd+1 where id = 'xx' 

上线一段时间后,很多报告进度都没有100%

2、问题排查

查看线上日志,发现生成附件2、附件3有时候会报错,然后对着报错改了代码,还是觉得有问题。因为看了代码,7个文件生成用的7个线程,每个结构都是try,catch,finnally,

看下面代码,感觉每个子线程都是走到finally里面,那就要么更新进度为100%,要么更新状态为失败

public void creatBgExcel(CreateBgWjPo createBgWjPo) {
..............................
        //附件1
        CompletableFuture<Void> task1 = CompletableFuture.runAsync(() -> {
            //新增数据excel,附件1
            createXzsjExcel(createBgWjPo, tempFileDir);
        }, threadPoolExecutor);

        //附件2
        CompletableFuture<Void> task2 = CompletableFuture.runAsync(() -> {
            //缺失数据excel,附件2
            createWtsjExcel(createBgWjPo, tempFileDir);
        }, threadPoolExecutor);

     ...............................
        CompletableFuture<Void> headerFuture = CompletableFuture.allOf(task1,task2 ,task3,.......);
        headerFuture.join();
        log.info("--bgId:{},excel报告单个附件已经全部生成", bgId);
    }

public void createWtsjExcel(CreateBgWjPo createBgWjPo, String tempFilePath) {log.info("--附件2,问题数据excel,开始生成数据,bgmc:{}", createBgWjPo.getGxZlbg().getBgmc());String exelxx = "";boolean isSucess = false;String msg = "";try{dosomething();isSucess = true;}catch (Exception e) {log.error("createWtsjExcel附件2生成失败,bgmc:{}",  createBgWjPo.getGxZlbg().getBgmc(),e);msg = "附件2生成excel失败.失败原因:{}" + e.getMessage();} finally {if (isSucess) {//更新进度gxZlbgMapper.updateBgJd(createBgWjPo.getGxZlbg().getId());} else {//更新状态bgZtToFail(createBgWjPo.getGxZlbg().getId(), msg, false, true);}}
}
(-)怀疑1,难道没有进入finally方法?
finanlly一般不执行的情况:
1、代码存在死循环
try{while(true){
}catch (Exception e) {} finally {
}
排查了代码,没有死循环,显然不适用。按理只要进入了子方法,肯定会进入finally。
排查线上日志docker logs -f --tail 100000 api-xx  grep 有问题的报告名称
发现: 有问题的报告名称,有些子文件没有打印出  开始生成数据的日志
结论: 有些报告生成的时候,根本没有进入对应的子方法
(2)排查方法外层代码ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(8, 10,10, TimeUnit.SECONDS,new LinkedBlockingQueue<>(Integer.MAX_VALUE));@Overridepublic SwaggerResultUtil<String> createZlbg(String bgId,boolean isReCreate) {CompletableFuture.runAsync(() -> {GxZlbg zlbg = new GxZlbg();zlbg.setId(bgId);//更新附件地址zlbg.setFjsczt(BgztEnum.DOING.getCode());zlbg.setWdsczt(BgztEnum.DOING.getCode());gxZlbgMapper.updateById(zlbg);CompletableFuture<Void> task1 = CompletableFuture.runAsync(() -> {//创建excelcreatBgExcel(result.getData());}, threadPoolExecutor);CompletableFuture<Void> task2 = CompletableFuture.runAsync(() -> {//创建wordcreateBgWord(result.getData());}, threadPoolExecutor);CompletableFuture<Void> headerFuture = CompletableFuture.allOf(task1, task2);headerFuture.join();}, threadPoolExecutor);return SwaggerResultUtil.resultSuccess();}

看到这段代码,发现存在线程池套线程池。

线程池8个,核心线程10个,问题分析

任务

外部线程

执行任务内部线程

备注

任务136里面子任务被执完成,外层的线程才会被释放
任务236
任务336

这样如果有3个报告同时生成,而且子文件方法耗时长,就会出现线程都被外部线程占用,内部无线程可用的状况,出现死锁,后续报告都无法开始生成。跟线上问题完全符合,应该就是发生了线程死锁

3、问题解决

不使用线程池套线程池的办法,把最外层方法指定线程池去掉threadPoolExecutor

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/645180.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于深度学习网络的十二生肖图像分类matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ............................................................... for i 1:16subplot(4,4,…

HubSpot功能有哪些?

HubSpot是一个功能丰富的平台&#xff0c;主要涵盖市场营销、销售、客户服务和客户关系管理&#xff08;CRM&#xff09;等领域。以下是HubSpot的一些主要功能&#xff1a; 市场营销自动化&#xff1a;HubSpot允许用户制定和执行多渠道的市场营销活动&#xff0c;包括创建和管…

为什么光电测径仪质量更稳定可靠?

光电测径仪与激光扫描式测径仪都是目前常用的外径自动化测量设备&#xff0c;他们能实现的功能相同&#xff0c;但为什么说光电测径仪更稳定可靠&#xff0c;下面一起来看一下。 光电测径仪测量原理 测头部件是测径仪的核心部件&#xff0c;它的作用是将被测物在CCD芯片上清晰…

redisson分布式锁的单机版应用

package com.redis;/*** author linn* date 2024年04月23日 15:31*/ import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.springframework.context.annotation.Bean; import org.springframework.context.…

怎样压缩jpg文件体积?分享一个极速压缩的方法

在工作中我们经常会遇到图片体积过大需要压缩处理。想要快速压缩jpg格式体积还不想下载软件要怎么操作呢&#xff1f;下面&#xff0c;给大家分享一款小白也能轻松使用的Jpg压缩&#xff08;https://www.yasuotu.com/&#xff09;工具-压缩图。支持上传单张100M以内&#xff0c…

常见大厂面试题(SQL)01

知乎问答最大连续回答问题天数大于等于3天的用户及其对应等级 1.描述 现有某乎问答创作者信息表author_tb如下(其中author_id表示创作者编号、author_level表示创作者级别&#xff0c;共1-6六个级别、sex表示创作者性别)&#xff1a; author_id author_level sex 101 …

命令行vue-cli-service不是内部或外部命令

没有安装vue/cli-service导致的 npm install -g vue/cli-service

背靠TON公链的Notcoin游戏项目,能否杀出GameFi的红海?

4月15日消息&#xff0c;Telegram生态中的游戏及Meme项目Notcoin&#xff0c;最近在X平台公布了令市场瞩目的代币经济学方案。据悉&#xff0c;NOT的总供应量高达1027亿枚&#xff0c;其中78%将分配给矿工和Voucher持有者&#xff0c;余下的22%预留给未来新用户、交易者及各类上…

MAC用户福利:一站式电商客服工具下载地址大全揭秘!

列举和比较拼多多商家版,阿里卖家MAC版本&#xff0c;京麦工作台&#xff0c;聊天宝MAC版&#xff0c;千牛MAC版&#xff0c;抖店MAC版各种适用于MAC系统的电商客服工具&#xff0c;提供平台MAC版本的下载地址&#xff0c;帮助用户提高客服效率、改善客户体验&#xff0c;从而提…

ROS通信模式/动作编程(设置收发节点,使小海龟移动到指定位置)

声明&#xff1a;本文转载&#xff0c;自己进行微微改动方便自己观看&#xff0c;有需要可以看原作者点击这里跳转 一、话题、服务模式编程 1.1 创建工作空间 输入以下三条命令&#xff1a; mkdir -p ~/comm_ws/src cd ~/comm_ws/src catkin_init_workspace编译工作空间&…

了解MySQL InnoDB多版本MVCC(Multi-Version Concurrency Control)

了解MySQL InnoDB多版本MVCC&#xff08;Multi-Version Concurrency Control&#xff09; 在数据库管理系统中&#xff0c;多版本并发控制&#xff08;MVCC&#xff09;是一种用于实现高并发和事务隔离的技术。MySQL的InnoDB存储引擎支持MVCC&#xff0c;这使得它可以在提供高…

U盘乱码频发,原因与解决方案大揭秘

在日常的工作和生活中&#xff0c;U盘因其便携性和大容量成为了我们不可或缺的存储设备。然而&#xff0c;有时候我们会遭遇U盘乱码的问题&#xff0c;这让我们无法正确读取和使用其中的文件。那么&#xff0c;U盘乱码究竟是何原因导致的呢&#xff1f;又该如何解决这一问题呢&…