当前位置: 首页 > news >正文

万万没想到在生产环境翻车了,之前以为很熟悉 CountDownLatch

  • 前言

  • 需求背景

  • 具体实现

  • 解决方案

  • 总结


前言 

之前我们分享了CountDownLatch的使用。这是一个用来控制并发流程的同步工具,主要作用是为了等待多个线程同时完成任务后,在进行主线程任务。然而,在生产环境中,我们万万没想到会出现问题。这是因为我们没有考虑到一些场景,导致了CountDownLatch出现了问题。

让我们来深入地了解一下由于CountDownLatch导致的问题。首先,我们需要明确的是,CountDownLatch是一个非常强大的工具。它可以帮助我们控制多个线程的执行过程,从而提高程序的并发性和效率。然而,如果我们没有正确地使用它,就可能会出现一些问题。

 

需求背景

先简单介绍下业务场景,针对用户批量下载的文件进行修改上传

为了提高执行的速度,我们採用了线程池来执行下载-修改-上传的操作。此外,我们还引入了CountDownLatch来控制线程之间的同步,以确保所有的操作都被正确执行。在所有线程完成之后,我们会将文件的地址保存到数据库中,以便之后的使用。这种方法不仅提高了程序的效率,而且减轻了线程的压力,从而使程序更加稳定可靠。

 

具体实现

根据服务本身情况,自定义一个线程池

 

模拟执行 

一开始我个人感觉没有什么问题,反正finally都能够做减一的操作,到最后调用await方法,进行主线程任务 

由于任务数量较多,阻塞队列中已经塞满了,所以线程池默认的拒绝策略会生效。当队列满时,处理策略会报错,并抛出异常。需要注意的是,这个异常是线程池自己抛出的,而非我们在循环中打印出来的。这种情况也会导致在线程池中断后,主线程会被打断,而await方法将无法执行。为了解决这个问题,我们可以利用jstack工具来查看线程池中的异常情况,并进行详细的分析和调试。此外,我们还可以进行一些优化措施,例如增加线程池的容量、调整任务队列的大小、优化任务处理策略等等,以提高线程池的性能和稳定性。 


解决方案 

为了解决阻塞队列过小导致的问题,我们可以考虑将其调大,但问题在于,应该调到多大才合适呢?如果调得太大,可能会带来内存溢出等其他问题。因此,我们需要在实际运行中不断测试和调整,找到一个适合当前情况的队列大小。

除了调整阻塞队列大小,我们还可以修改拒绝策略。在触发拒绝策略时,可以使用调用者所在的线程来执行任务。这种做法可以避免因线程池过载导致的任务执行失败。当然,这也可能会带来一些新的问题,例如如果调用者线程本身就很繁忙,可能会导致更多任务积压。因此,我们需要根据实际情况进行权衡和调整。

你可能会担心任务数量太多,导致调用者所在的线程执行不过来,从而导致任务提交的性能急剧下降。但是,不要担心,我们可以通过自定义拒绝策略来解决这个问题。我们可以将排队的消息记录下来,采用补偿机制的方式去执行,从而避免任务数量太多的问题。这样,您就可以放心地提交任务,无需担心性能问题。

同时,我们也需要注意线程池可能会抛出异常。因此,我们需要在代码中加入try catch语句,以记录问题数据。在finally中,我们还需要执行countDownLatch.countDown语句,以避免线程池的使用出现问题。这样,我们就可以更好地使用线程池,并且避免出现不必要的问题。


总结 

根据业务部门的反馈,我们发现在实际业务中任务数量并不是很多。这可能是因为我们的系统中存在一些瓶颈,导致流程无法顺畅地进行。因此,我们决定先采用第二种方式来尝试解决这个线上问题。虽然这种方式可以解决目前的问题,但我们需要注意到,如果没有正确地关闭countDownLatch,就会导致一直等待。为了避免这个问题,我们需要对代码进行一些修改,以确保其正常运行。

另外,我们需要意识到,工具虽然是好的,但其使用也可能带来一些问题。如果我们没有正确地处理,就会引发一系列连锁反应。因此,我们需要仔细地评估工具的使用,以确保我们能够使其发挥最大的效益,同时避免潜在的问题。我们可以考虑对新工具进行一些测试,以确保其稳定性和可靠性。此外,我们还可以开发一些新的功能,以提高我们的工作效率。这些功能可以包括自动化流程、数据分析和报告生成等。

相关文章:

万万没想到在生产环境翻车了,之前以为很熟悉 CountDownLatch

前言 需求背景 具体实现 解决方案 总结 前言 之前我们分享了CountDownLatch的使用。这是一个用来控制并发流程的同步工具,主要作用是为了等待多个线程同时完成任务后,在进行主线程任务。然而,在生产环境中,我们万万没想到会…...

Springboot整合Jasypt实战

Springboot整合Jasypt实战 引入依赖 <dependency><groupId>com.github.ulisesbocchio</groupId><artifactId>jasypt-spring-boot-starter</artifactId><version>3.0.5</version> </dependency>配置jasypt # 配置jasypt相关信息…...

计算机网络笔记:DNS域名解析过程

基本概念 DNS是域名系统&#xff08;Domain Name System&#xff09;的缩写&#xff0c;也是TCP/IP网络中的一个协议。在Internet上域名与IP地址之间是一一对应的&#xff0c;域名虽然便于人们记忆&#xff0c;但计算机之间只能互相认识IP地址&#xff0c;域名和IP地址之间的转…...

C语言函数大全-- s 开头的函数(4)

C语言函数大全 本篇介绍C语言函数大全-- s 开头的函数&#xff08;4&#xff09; 1. strdup 1.1 函数说明 函数声明函数功能char * strdup(const char *s);用于将一个以 NULL 结尾的字符串复制到新分配的内存空间中 注意&#xff1a; strdup() 函数返回指向新分配的内存空间…...

Linux常见指令 (2)

Linux常见指令 ⑵ 补充man描述:用法:例子 echo描述:用法:例子 echo 字符串例子 echo 字符串 > 文件例子 追加重定向(>>)例子 输出重定向(>)来创建文件 && (>)来清空文件 cat描述:用法:例子 cat && cat 文件补充:例子 cat 文件 && cat &…...

shell脚本4

字符串变量 格式介绍&#xff1a;单引号 varabc 双引号 var"abc" 不使用引号 varabc 区别&#xff1a;单引号&#xff0c;原样输出&#xff0c;不会解析里面的变量 双引号&#xff0c;会解析变量&#xff0c;并且可以使用子双引号&#xff0c;需要转…...

递归思路讲解

最近刷到了树这一模块的算法题&#xff0c;树相关的算法题几乎都是用递归来实现的&#xff0c;但递归的思路却有点抽象&#xff0c;每次遇到递归&#xff0c;都是通过递归来深度或广度地遍历树&#xff0c;但对于递归遍历树的遍历路线&#xff0c;却有点抽象难懂&#xff0c;不…...

基于R语言APSIM模型高级应用及批量模拟

目录 专题一 APSIM模型应用与R语言数据清洗 专题二 APSIM气象文件准备与R语言融合应用 专题三 APSIM模型的物候发育和光合生产模块 专题四 APSIM物质分配与产量模拟 专题五 APSIM土壤水平衡模块 专题六 APSIM土壤碳、氮平衡模块 专题七 APSIM农田管理模块与情景模拟 专…...

Hyperf中的其它事项

Hyperf中的其它事项 关于 Hyperf 其它的内容我们就不多说了&#xff0c;毕竟框架这东西用得多了自然也就熟悉了。最重要的是——我的水平还不足以去深入地分析这个框架&#xff01; 好吧&#xff0c;其它的功能大家可以去官方文档详细了解&#xff0c;毕竟国人自己做的框架&a…...

【技术选型】Elasticsearch 和Solr那个香?

我们为什么在这里&#xff1f;我存在的目的是什么&#xff1f;我应该运动还是休息并节省能量&#xff1f;早起上班或晚起并整夜工作&#xff1f;我应该将炸薯条和番茄酱或蛋黄酱一起吃吗&#xff1f; 这些都是古老的问题&#xff0c;可能有也可能没有答案。其中一些是非常困难或…...

4面美团测试工程师,因为这个小细节,直接让我前功尽弃.....

说一下我面试别人时候的思路 反过来理解&#xff0c;就是面试时候应该注意哪些东西&#xff1b;用加粗部分标注了 一般面试分为这么几个部分&#xff1a; 一、自我介绍 这部分一般人喜欢讲很多&#xff0c;其实没必要。大约5分钟内说清楚自己的职业经历&#xff0c;自己的核…...

数据恢复软件EasyRecovery16下载安装步骤教程

EasyRecovery16是一款专业好用的数据恢复软件&#xff0c;软件提供了向导式的操作向导&#xff0c;可以有效地恢复电脑或者移动存储设备中丢失的各种文件&#xff0c;包括删除的文件、格式化丢失的文件和清空回收站的数据!千呼万唤始出来&#xff0c;大家期盼许久的EasyRecover…...

Springboot 自定义缓存配置 CacheManager 及redis集成

目录 前言 集成 maven依赖 CacheManagerConfig配置 redis配置 使用 Springboot 集成使用缓存 Cacheable CacheEvict 前言 现有项目中经常遇到的缓存集成问题&#xff0c;Springboot提供了统一的接口抽象与缓存管理器&#xff0c;可集成多种缓存类型&#xff0c;如 Co…...

JS 中七个改变原数组的方法

目录 一、push 二、pop 三、unshift 四、shift 五、splice 六、sort 七、reverse 一、push 在数组的尾部添加元素&#xff0c;并返回新的长度。 let arr [1] arr.push(2) console.log(arr) // [1, 2] 二、pop 删除数组最后面一个元素、并返回删除的元素。 let arr [1, …...

【笔试强训选择题】Day7.习题(错题)解析

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;笔试强训选择题 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01; 文章目录…...

Vue电商项目--axios二次封装

postman测试接口 刚刚经过postman工具测试&#xff0c;发现接口果然发生了改变。 新的接口为http://gmall-h5-api.atguigu.cn 如果服务器返回的数据code字段200&#xff0c;代表服务器返回数据成功 整个项目&#xff0c;接口前缀都有/api字样 axios二次封装 XmlHttpRequ…...

人生四维度

人生四维度 不是有钱了就成功&#xff0c;你知道&#xff1b;人生的成功不止一种&#xff0c;你也知道。但成功还有哪种&#xff1f;你知道吗&#xff1f; 如果把人生的体验展开&#xff0c;我们可以得到四个维度&#xff0c;高度、深度、宽度和温度。 财富、权力、影响力 构…...

Python 调用 MessageBeep 播放系统音效

Python 调用 MessageBeep 播放 Windows 系统提示声音 Windows API 函数 "MessageBeep" 介绍 "Windows API MessageBeep"是一个用于发出系统提示音效的函数。它可以向用户发出一种预定义的声音&#xff0c;以指示事件的发生或某个条件的满足。例如&#xf…...

废物,我TMD一个985却斗不过专科生(大厂自动化测试2年被裁)

前言 看到标题&#xff0c;可能很多读者朋友恐怕又要骂我了&#xff0c;985这个特殊的字眼也确实异常晃眼&#xff0c;实际上现在985&#xff0c;211也越来越多&#xff0c;它能代表你能够进入到更高的平台&#xff0c;拿到“高级工厂”的入场券&#xff0c;但并不意味着你会成…...

p70 内网安全-域横向内网漫游 Socks 代理隧道技术(NPS、FRP、CFS 三层内网漫游)

数据来源 本文仅用于信息安全学习&#xff0c;请遵守相关法律法规&#xff0c;严禁用于非法途径。若观众因此作出任何危害网络安全的行为&#xff0c;后果自负&#xff0c;与本人无关。 ​ 必要基础知识点&#xff1a; 内外网简单知识内网 1 和内网 2 通信问题正向反向协议通…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

LLMs 系列实操科普(1)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…...

jmeter聚合报告中参数详解

sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample&#xff08;样本数&#xff09; 表示测试中发送的请求数量&#xff0c;即测试执行了多少次请求。 单位&#xff0c;以个或者次数表示。 示例&#xff1a;…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing

Muffin 论文 现有方法 CRADLE 和 LEMON&#xff0c;依赖模型推理阶段输出进行差分测试&#xff0c;但在训练阶段是不可行的&#xff0c;因为训练阶段直到最后才有固定输出&#xff0c;中间过程是不断变化的。API 库覆盖低&#xff0c;因为各个 API 都是在各种具体场景下使用。…...

go 里面的指针

指针 在 Go 中&#xff0c;指针&#xff08;pointer&#xff09;是一个变量的内存地址&#xff0c;就像 C 语言那样&#xff1a; a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10&#xff0c;通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...

uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)

UniApp 集成腾讯云 IM 富媒体消息全攻略&#xff08;地理位置/文件&#xff09; 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型&#xff0c;核心实现方式&#xff1a; 标准消息类型&#xff1a;直接使用 SDK 内置类型&#xff08;文件、图片等&#xff09;自…...