欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 创投人物 > java线程池bug的一些思考

java线程池bug的一些思考

2024/10/26 1:30:38 来源:https://blog.csdn.net/davidmeng6628/article/details/143051283  浏览:    关键词:java线程池bug的一些思考

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

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

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

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

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

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

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

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

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

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

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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com