Java Executors中的空闲线程是否会占用CPU执行时间?

7
当我在应用程序中有这段代码时:
Executors.newFixedThreadPool(4);

但我从未使用过这个线程池。空闲的线程会消耗CPU时间吗?如果会,为什么?


7
不。空闲线程不会消耗CPU时间(虽然启动池需要时间,且会占用内存)。 - Elliott Frisch
如果我没记错的话,调用那个方法并不会真正地“启动”池。请看我的回答。 - GhostCat
只是好奇:有什么阻止你接受其中一个答案的吗? - GhostCat
2个回答

5
不,这些线程是按需创建的。正如文档中所述(强调我的):

按需构建

默认情况下,即使是核心线程也仅在有新任务到达时才会被创建和启动。

Java提供了覆盖此默认设置并允许急切创建的方法,即prestartCoreThreadprestartAllCoreThreads
一旦线程实际上被创建,空闲的线程(通常)不会占用CPU时间,因为它们没有工作需要在核心上安排。
然而,它们仍然会保留一些内存,例如它们的堆栈等。

4

javadoc中写道:

创建一个线程池,它重用一定数量的线程,这些线程从共享的无界队列中操作。在任何时候,最多nThreads个线程将活动地处理任务。

这可能会导致我们做出假设:我们不确定。但是正如其他答案清楚地发现的那样 - 我们可以知道,并且实现实际上完全懒惰。因此:

 ExecutorService service = Executors.newFixedThreadPool(4);

这甚至不需要太多的设置。实现可以自由等待任何

 service.submit(...

发生的情况。
另一方面,该线程池(理论上)可以立即创建,并且还可以创建4个操作系统线程。如果是后者,则所有这些线程都将处于空闲状态,因此它们不应消耗任何CPU资源。
但当然,正如Elliott正确指出的那样,创建池和(潜在地)创建1到4个线程的初始步骤需要CPU活动。
当然:线程是操作系统资源。因此,即使它们“只存在”并且什么也不做,它们也有“成本”。再次强调,这可能取决于操作系统是否会成为问题(例如达到某个“现有线程的最大数量”限制)。

最后:由于这让我很好奇,我查看了当前Java8源代码(从newFixedThreadPoo()ThreadPoolExcecutor()DefaultThreadFactory)。如果我没有错的话:这些构造函数仅为线程创建做准备。

因此,“当前”实现是“完全”的惰性;如果您真的只调用newFixedThreadPool()而从未使用生成的ExecutorService……则不会发生任何事情(就新线程创建而言)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接