在 Java 中完成任务时线程在增加但不减少

Posted

技术标签:

【中文标题】在 Java 中完成任务时线程在增加但不减少【英文标题】:Threads are increasing but not decreasing when the task finished in Java 【发布时间】:2021-11-11 07:15:42 【问题描述】:

我有一个应用程序,我做了如下线程配置,

corepoolsize = 10
maxpoolsize = 10
queuecapacity = 10

但是当我使用在线程上运行的线程和函数时(异步进程) 我看到它正在增加,如下所示,但我没有看到线程在减少。这是内存泄漏的迹象吗?有人可以指导我吗?

这样打印日志,

2021-09-15 01:13:48.554  INFO 111 --- [Async-1]
2021-09-15 01:13:48.654  INFO 121 --- [Async-2]
2021-09-15 01:13:48.754  INFO 132 --- [Async-3]
2021-09-15 01:13:48.854  INFO 140 --- [Async-4]
2021-09-15 01:13:48.954  INFO 155 --- [Async-5]
2021-09-15 01:13:49.554  INFO 160 --- [Async-6]

但我没有看到它再次像那样调用[Async-1], [Async-2]。这是内存泄漏还是线程缓存,还是在填满 corepoolsize 之后它会运行[Async-1]

【问题讨论】:

您能否添加一个完整的示例来重现该问题?我们无法提供其他帮助,因为我们无法理解您面临的问题。 您的核心池大小为10,因此核心池将包含线程Async-1Async-10 在10 个任务之后我假设执行任务的下一个线程可能是最闲的一个。请注意,它将是之前创建的 10 个中的一个 来自 ThreadPoolExecutor:corePoolSize - 保留在池中的线​​程数,即使它们处于空闲状态,除非设置了 allowCoreThreadTimeOut。没有泄漏,尽管您可以将其设置为例如 2。 【参考方案1】:

Corepoolsize 表示始终处于活动状态的工作线程。

你可以查看ThreadPoolExecutor#runWorkerThreadPoolExecutor#getTask方法,这些工作线程总是会尝试从任务队列中获取任务并执行它们。所以如果没有新的任务发布到线程池,那么这些工作线程会一直活着,通常阻塞在workQueuetake方法中,所以你不用担心cpu空闲。

corepoolsize数量以外的worker线程会被回收,还是ThreadPoolExecutor#getTask方法:

           try 
                Runnable r = timed ?
                    workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                    workQueue.take();
                if (r != null)
                    return r;
                timedOut = true;
             catch (InterruptedException retry) 
                timedOut = false;
            

这些要回收的线程最多可以存活keepAliveTime时间。

线程池使用Hash表来保存线程的引用,这样线程的生命周期就可以通过添加和删除引用等操作来控制。(ThreadPoolExecutor#processWorkerExit方法)。

【讨论】:

【参考方案2】:

这是预期的行为。 ThreadPoolExecutor 的文档明确指出:

在execute(Runnable)方法中提交新任务时,如果运行的线程数少于corePoolSize,则创建一个新线程来处理该请求,即使其他工作线程处于空闲状态。

【讨论】:

问题中没有证据表明他正在使用ThreadPoolExecutor @user207421 存在某种线程池。 @user207421 OP 写了关于配置参数“corepoolsize”、“maxpoolsize”和“maxpoolsize”,他还提到了“spring-boot”,它使用ThreadPoolExecutor 来执行异步任务,所以它预计在幕后使用 ThreadPoolExecutor 似乎是合理的。 @JoopEggen 当然,但问题中没有关于ThreadPoolExecutor 的内容。如果从证据中得出该结论的有效推论,则应该在答案中提供。

以上是关于在 Java 中完成任务时线程在增加但不减少的主要内容,如果未能解决你的问题,请参考以下文章

java 线程池ThreadPoolExecutor 共同完成一个任务

Java线程池

java线程池技术

java多线程 -- 线程池

什么是线程池

Java 线程池