在 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-1
到Async-10
在10 个任务之后我假设执行任务的下一个线程可能是最闲的一个。请注意,它将是之前创建的 10 个中的一个
来自 ThreadPoolExecutor:corePoolSize - 保留在池中的线程数,即使它们处于空闲状态,除非设置了 allowCoreThreadTimeOut。没有泄漏,尽管您可以将其设置为例如 2。
【参考方案1】:
Corepoolsize
表示始终处于活动状态的工作线程。
你可以查看ThreadPoolExecutor#runWorker
,ThreadPoolExecutor#getTask
方法,这些工作线程总是会尝试从任务队列中获取任务并执行它们。所以如果没有新的任务发布到线程池,那么这些工作线程会一直活着,通常阻塞在workQueue
的take
方法中,所以你不用担心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 中完成任务时线程在增加但不减少的主要内容,如果未能解决你的问题,请参考以下文章