有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

有多个执行器是安全的。Java程序中的newCachedThreadPool()?

此方法的规范:https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html#newCachedThreadPool()

Creates a thread pool that creates new threads as needed, but will reuse previously constructed threads when they are available. These pools will typically improve the performance of programs that execute many short-lived asynchronous tasks. Calls to execute will reuse previously constructed threads if available. If no existing thread is available, a new thread will be created and added to the pool. Threads that have not been used for sixty seconds are terminated and removed from the cache. Thus, a pool that remains idle for long enough will not consume any resources. Note that pools with similar properties but different details (for example, timeout parameters) may be created using ThreadPoolExecutor constructors.

从这个描述中我不清楚-在一个程序中有几个这样的池安全吗?或者,我可能会遇到一个池在多个线程上暂停并冻结其他池的情况吗


共 (1) 个答案

  1. # 1 楼答案

    我认为这个问题没有明确的是/否答案

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

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

    • OS可能对其支持的本机线程总数有严格限制

    • OS可以限制给定进程(在本例中是JVM)可以创建的本机线程的数量。这可以通过使用ulimitcgroup限制,以及可能的其他方式来实现

    • 在典型的64位JVM上,Java线程堆栈的大小为1MB(默认情况下)。如果你试图start()过多的线程,你可能会耗尽内存并得到一个OOME

    • 如果有足够多的线程和/或太多的线程上下文切换,线程调度程序(在操作系统中)可能会陷入困境

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

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

    • 锁定共享对象时死锁
    • 共享锁上的争用过多导致资源匮乏
    • 太多工作导致超时,或
    • 优先级反转问题。。。如果你试图使用优先级来“管理”工作量

    所以

    Is it safe to have several of these pools in a single program?

    Or would I potentially run into a situation where one pool stalls on many threads and freezes up other pools.

    你不太可能得到一个“摊位”。。。除非任务以某种方式相互作用

    但是,如果有太多的可运行线程在争夺CPU,那么每个线程(平均而言)在有限的可用内核数量中所占的份额会更小。锁争用或过多的上下文切换会进一步降低速度