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

java线程池bug的一些思考

科学需要对前人的怀疑,对权威的怀疑。

但是上学的时候,我们也需要去理解课本。

现在网上充斥了“java 线程池的缺点”这一观点。分析了一下线程池的工作原理,确实也存在这些问题。

Java线程池工作原理。核心线程数,最大线程数,任务队列,当任务超过核心线程数的时候,就会往任务队列里面放,如果超过任务队列数量那么就会增加线程数到最大线程数。然后多个线程继续处理。如果再放进去,就会执行拒绝策略。

JAVA默认创建的线程池,是一个无限的任务队列,如果在任务数量足够的多情况下,就会OOM”。这是一个bug。

知道了原理,我们还是还原使用场景。

之前自己使用了一次,就是取1000W的数据,然后在对每个文件进行处理。因为涉及到文件处理,我就想使用多线程。数据库我使用的是JPA,然后我就遇到了第一个问题,发现使用Stream<T> 跟自己想象的不一样。造成了大量的GC,最后OOM了。然后就是通过之前JPA 获取大量数据进行处理的。从数据库返回的数据不是全部添加到内存中。

后面的代码就很简单,放到线程池去处理就好了。然后发现,虽然从数据库返回的数据不全部在内存,但是都放到了任务队列里面了。内存还是没有减少。不过没有造成数据再内存里翻倍,(一份是数据库的List,然后还都在任务队列里面有一份,如果任务队列里面的数据和数据库返回的是一致的,应该多出来的是那么多指针。) ps:上诉问题最好的解决方式就是加内存,可以很快的解决问题。通过代码来优化,就比较耗时了。

其实我理想的方式是,我从数据库取100个,然后交给线程池处理,处理了差不多了,在从数据库取一部分。这样就可以大量的减少内存的使用,只不过发现这种很复杂。感觉有些和reactive差不多的感觉。

还有一种我想到的线程池使用的大量场景就是任务接受。不停的给服务器发送任务。造成了任务队列边长,消化不完造成OOM。其实我觉得这种解决方式是增加新的pod,而不是修改任务队列的固定长度,最后通过拒绝策略拒绝掉。或者通过限流,来控制任务的来源,把处理不了的任务,拒绝在最前端,而不是直接交给后面的线程池直接处理。那样就算你只用固定长度的任务队列,还是会执行拒绝策略,那么你还得处理被拒绝的任务。

最后就想说,不是屈服JDK的权威,说他们设计的有问题。我觉得所有的观点都有道理,具体问题具体分析吧。不要只有一个声音就好。

http://www.lryc.cn/news/466334.html

相关文章:

  • 深入解析浮动布局及其在现代Web开发中的应用与替代(浮动的概念及应用、如何清除浮动、使用Flex布局和Grid布局的区别、使用`float`布局的历史和现状)
  • WPF基础权限系统
  • 【Java函数篇】Java 8 Predicate函数接口的用法详解
  • C++ 一个反射的例子
  • vue3 解决背景图与窗口留有间隙的问题
  • Cesium for UE-04-一些说明
  • AIGC:开启智能创造的璀璨新篇章
  • 计算机组成原理与系统结构——外部存储器
  • 如何使用 Browserless 抓取动态网站?
  • 第21~22周Java主流框架入门-Spring 2.SpringAOP面向切面编程
  • Flutter不常用组件----InteractiveViewer
  • 【LeetCode HOT 100】详细题解之二分查找篇
  • 管理篇(顶级思维模型(31个))(待做)
  • 十一、数据库配置
  • day02 -- docker
  • ecmascript标准
  • 在Linux命令行中一行执行多个命令
  • u盘快速格式化后怎么恢复文件:深入解析与全面指南
  • 青少年编程能力等级测评CPA C++(二级)试卷(2)
  • aws 把vpc残留删除干净
  • 平衡二叉树最全代码
  • 数据库表的创建
  • 【MySQL 数据库】之--基础知识
  • Flume面试整理-如何处理Flume中的数据丢失
  • 文件处理新纪元:微信小程序的‘快递员’与‘整理师’
  • 应付账款优化,自动化管理5要点
  • Win安装Redis
  • 手把手带你安装U9【win10+sql+U9】,同样适用U9C的安装
  • 若依前后端框架学习——新建模块(图文详解)
  • 【LaTeX和Word版】写论文时如何调整公式和文字的间距