为了账号安全,请及时绑定邮箱和手机立即绑定

在 Java 程序中有多个 Executors.newCachedThreadPool()

在 Java 程序中有多个 Executors.newCachedThreadPool()

天涯尽头无女友 2023-05-17 16:48:40
此方法的规范:https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html#newCachedThreadPool()创建一个线程池,该线程池根据需要创建新线程,但会在可用时重用以前构造的线程。这些池通常会提高执行许多短期异步任务的程序的性能。如果可用,对执行的调用将重用以前构造的线程。如果没有可用的现有线程,将创建一个新线程并将其添加到池中。60 秒内未使用的线程将被终止并从缓存中删除。因此,保持空闲时间足够长的池不会消耗任何资源。请注意,可以使用 ThreadPoolExecutor 构造函数创建具有相似属性但不同细节(例如,超时参数)的池。从这个描述中我不清楚 - 在一个程序中拥有多个这样的池是否安全?或者我是否会遇到这样一种情况,即一个池在多个线程上停顿并冻结其他池?
查看完整描述

1 回答

?
潇湘沐

TA贡献1816条经验 获得超6个赞

我认为对此没有明确的是/否答案。

一方面,ThreadPoolExecutor 实例消耗的线程数量不是有限的。JVM 体系结构本身不限制线程数。

另一方面,操作系统/环境可能会有一些限制:

  • 操作系统可能对其支持的本机线程总数有硬性限制。

  • 操作系统可能会限制给定进程(在本例中为 JVM)可以创建的本机线程数。这可以使用ulimitcgroup限制以及其他可能的方式来完成。

  • 在典型的 64 位 JVM 上,Java 线程堆栈的大小为 1MB(默认情况下)。如果您尝试使用start()太多线程,则可能会耗尽内存并出现 OOME。

  • 如果有足够多的线程和/或过多的线程上下文切换,线程调度程序(在操作系统中)可能会遇到困难。

    (上下文切换通常发生在线程执行阻塞系统调用或必须等待锁定或通知时。每次切换上下文时都会产生与硬件相关的开销:保存和恢复寄存器、切换虚拟内存上下文、刷新内存缓存等。 )

第三,除了线程池的数量和大小之外,还有其他因素可能会导致问题。例如,如果线程任务相互交互,您可能会遇到以下问题:

  • 锁定共享对象时发生死锁,

  • 过多的共享锁争用导致资源匮乏,

  • 太多的工作导致超时,或者

  • 优先级倒置问题……如果您尝试使用优先级来“管理”工作量。

所以 ...

在一个程序中拥有多个这样的池是否安全?

或者我是否会遇到这样一种情况,即一个池在多个线程上停滞并冻结其他池。

除非任务以某种方式相互作用,否则您不太可能会遇到“停顿” 。

但是,如果您有太多可运行的线程竞争 CPU,每个线程将(平均)获得有限数量的可用内核中的一小部分。锁争用或过多的上下文切换会进一步减慢速度。


查看完整回答
反对 回复 2023-05-17
  • 1 回答
  • 0 关注
  • 97 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信