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

线程池遇到父子任务,有大坑,要注意!

老规矩,还是先上个代码:

这个代码的逻辑非常简单,首先我们搞了一个线程池,然后起一个 for 循环往线程池里面仍了 5 个任务,这是核心逻辑。

对于这几个任务,我们的这个自定义线程池处理起来,不能说得心应手吧,至少也是手拿把掐。

其他的 StopWatch 是为了统计运行时间用的。 至于 CountDownLatch,你可以理解为在业务流程中,需要这五个任务都执行完成之后才能往下走,所以我搞了一个 CountDownLatch。

这个代码运行起来是没有任何问题的,我们在日志中搜索“执行完成”,也能搜到 5 个,这个结果也能证明程序是正常结束的:

同时,可以看到运行时间是 4s。

示意图大概是这样的:

然后歪师傅看着这个代码,发现了一个可以优化的地方:

这个地方从数据库捞出来的数据,它们之间是没有依赖关系的,也就是说它们之间也是可以并行执行的。

所以歪师傅把代码改成了这样:

在异步线程里面去处理这部分从数据库中捞出来的数据,并行处理加快响应速度。

对应到图片,大概就是这个意思:

把程序运行起来之后,日志变成了这样:

我们搜索“执行完成”,也能搜到 5 个对应输出。

而且我们就拿“任务2”来说:

当前线程pool-1-thread-3,---【任务2】开始执行--- 当前线程pool-1-thread-3,---【任务2】执行完成--- 当前线程pool-1-thread-1,【任务2】开始处理数据=1 当前线程pool-1-thread-2,【任务2】开始处理数据=2

从日志输出来看,任务 2 需要处理的两个数据,确实是在不同的异步线程中处理数据,也实现了我的需求。

但是,程序运行直接就是到了 9.9ms:

这个优化这么牛逼的吗?

从 4s 到了 9.9ms?

稍加分析,你会发现这里面是有问题的。

那么问题就来了,到底是啥问题呢?

你也分析分析大概是啥问题,别老是想着直接找答案啊。

问题就是由于转异步了,所以 for 循环里面的任务中的 countDownLatch 很快就减到 0 了。

于是 await 继续执行,所以很快就输出了程序运行时间。

然而实际上子任务还在继续执行,程序并没有真正完成。

9.9ms 只是任务提交到线程池的时间,每个任务的数据处理时间还没算呢:

从日志输出上也可以看出,在输出了 StopWatch 的日志后,各个任务还在处理数据。

这样时间就显得不够真实。

那么我们应该怎么办呢?

很简单嘛,需要子任务真正执行完成后,父任务的 countDownLatch 才能进行 countDown 的动作。

具体实现上就是给子任务再加一个 countDownLatch 栅栏:

我们希望的运行结果应该是这样的:

当前线程pool-1-thread-3,---【任务2】开始执行--- 当前线程pool-1-thread-1,【任务2】开始处理数据=1 当前线程pool-1-thread-2,【任务2】开始处理数据=2 当前线程pool-1-thread-3,---【任务2】执行完成---

即子任务全部完成之后,父任务才能算执行完成,这样统计出来的时间才是准确的。

思路清晰,非常完美,再次运行,观察日志我们会发现:

http://www.jsqmd.com/news/1105678/

相关文章:

  • openEuler/kiran-tests核心组件揭秘:Behave BDD框架与自动化测试实践
  • STM32与13DOF传感器融合开发实战
  • 终极免费解锁Wand专业版:开源增强工具完整指南
  • 6.25小学期CPP基础语法记录:反转、字符串查找、稳定sort
  • STM32G491RE与TPAFE0808实现多通道信号采集方案
  • GPT-5.5 多智能体协作能力初探:构建自主任务流的技术验证
  • 【课程设计/毕业设计】基于 SpringBoot 的宠物医院物资设备一体化管理系统的设计与实现【附源码、数据库、万字文档】
  • 知医邦ChatiSS查体大模型:四大核心应用场景全面赋能中医全生命周期
  • 别再Ctrl+F了!用IDEA书签实现毫秒级代码定位(附性能对比数据:平均跳转耗时降低87.3%)
  • 5分钟解锁3D魔法:用Deep3D让普通视频瞬间立体化!
  • Python自动化测试实战:从Selenium到Playwright,构建高效测试框架
  • Linux打印机驱动配置终极指南:foo2zjs让100+型号打印机完美工作
  • MAA明日方舟智能助手完整使用指南:5分钟快速上手解放双手
  • 2026年7月最新小程序开发公司深度评测:技术实力、交付能力与行业口碑全景解析,含零代码SAAS、AI编程、源码定制
  • 游戏机变身B站神器:wiliwili让你的Switch、PSVita秒变追番利器
  • 【Springboot毕设全套源码+文档】基于Java+springboot家装项目管理系统的设计与实现(丰富项目+远程调试+讲解+定制)
  • 全面解锁Nintendo Switch潜能:Atmosphere大气层系统深度解析
  • Linux应急响应实战:从入侵检测到溯源加固的必备工具集
  • IDEA依赖冲突解决全攻略:5步定位+3招修复+1键清理,Maven Helper实战手册限时公开
  • Ubuntu 18.04下phpMyAdmin安全加固实战指南
  • ASM330LHH与TM4C123GH6PZ运动跟踪系统设计
  • AI率总超标?2026年AI写作辅助软件排行榜权威发布,一次过审不是梦!
  • 巨杉数据库的msyql兼容模式关于对象存储的功能
  • MC74HC165A并行输入芯片在嵌入式系统中的应用与优化
  • TomcatScanPro:自动化Tomcat安全扫描与漏洞利用实战指南
  • Hermes接入stepfun阶跃星辰Step API教程(使用step-3.7-flash大模型)
  • SSH密钥交换算法加固指南:从CVE漏洞到现代ECDH配置实战
  • Flux2 文生图/图生图整合包本地化部署与极限显存优化
  • 保姆级教程:让你的 Node.js 应用永远在线的神器——PM2
  • LLM代码生成不是自我编程,而是软件工作流重编排