在应用程序生命周期内创建的最大线程池数量是不是有限制?

Posted

技术标签:

【中文标题】在应用程序生命周期内创建的最大线程池数量是不是有限制?【英文标题】:Is there a limit on the maximum number of threadpools created during an application lifetime?在应用程序生命周期内创建的最大线程池数量是否有限制? 【发布时间】:2021-07-14 06:47:19 【问题描述】:

考虑以下代码:

class Test 
    public static void main(String... args) 
        var t = new Test();
        while(true) 
            t.work();
        
    
    public void work() 
        ExecutorService executorService = Executors.newFixedThreadPool(10);

        try 
             /* Do work */
        
        finally 
            executorService.shutdown();
        
    

在应用程序的生命周期内(不是同时)可以有多少个线程池。

我尝试查看源代码并运行此测试一段时间,但似乎没有限制。一旦线程池计数器溢出会发生什么?

【问题讨论】:

没有明确的限制。 但是请注意,启动/停止线程需要一些时间,因此为所有工作操作使用同一个线程池可能比为每个操作创建一个新线程池更快。跨度> 【参考方案1】:

(在 Java 11 中)对线程池的数量没有特定限制,并且没有可能溢出的线程池计数器。

线程有一个 ID / 序列号,但由于它的类型是 long 并且仅在创建新的 Thread 时才加一,因此溢出不是实际问题1.

但是,线程 ... 尤其是 live 线程2 ... 会占用大量内存。因此,您不能同时存在无限数量的活动线程或线程池。


1 - 算一下。应用程序创建 2^63 个线程需要多长时间...假设有足够的内存等。 2 - 已启动但尚未终止的线程。

【讨论】:

无论如何都无需担心潜在的线程 ID 耗尽,因为允许实现重用已终止线程的 ID。因此,同时只有 2⁶³ 非终止线程会耗尽 ID 范围(这将需要 n × 2⁶³ 字节的运行时内存,而 n 的实际值无关紧要) … 确实如此。但是,在当前实现中,如果您确实(假设地)设法使线程 ID 溢出,则可以为仍然存在的线程重用线程 ID。我不认为他们检查。 (他们为什么会这样?) 我想,ID 会首先溢出到负数中,我们不知道实现是否会对此进行检查。如果不是,第一个违规行为是线程 ID 为负,而不是重复 ID。但是,我认为我们同意,当当前计算机架构无法实现该场景时,无需检查实现。但是当这成为一个问题时,规范允许更新实现。 顺便说一句,有一个“可能溢出的线程池计数器”。它的唯一用途似乎是线程名称生成。我刚刚验证过了。第 2147483647 个线程池的第一个线程的名称为 pool-2147483647-thread-1,下一个池的名称为 pool--2147483648-thread-1,然后是 pool--2147483647-thread-1,以此类推 哦。我找了一个柜台,没有找到。我再看看。【参考方案2】:

没有限制。但是线程会占用自己的资源。因此,这取决于服务器中有多少资源(CPU、内存等)以及分配给 JVM 的资源有多少。如果线程数吃光了所有资源,你的 JVM 就会崩溃。

【讨论】:

以上是关于在应用程序生命周期内创建的最大线程池数量是不是有限制?的主要内容,如果未能解决你的问题,请参考以下文章

线程池概述

Java多线程 线程池的生命周期及运行状态

线程池

JAVA 线程池原理

线程池的前世今生

Java多线程学习之线程池详解