2017-02-08 65 views
1

如果我有一个固定大小的线程池,它何时会实际调用Thread.start()来启动线程? (它会启动这些它被创建时,还是会等到我开始提交任务?)在线程池中创建实际的线程

+0

你的问题对我来说不是很清楚。 – Sid

+0

可能的重复[如何Threadpool重用线程和它如何工作](http://stackoverflow.com/questions/19765904/how-threadpool-re-use-threads-and-how-it-works) – Calculator

回答

1

如果创建一个固定大小的线程池是这样的:

ExecutorService es = Executors.newFixedThreadPool(5); 

没有线程最初创建。当您提交第一个任务时,只创建一个线程(它被命名为“pool-1-thread-1”)

对于每个额外提交的任务,创建一个新的线程直到指定的固定大小在这个例子中),即使任务没有真正并行运行

如果,例如,您只能提交3个任务,只有3个线程将具有以下名称创建: pool-1-thread-1 pool-1-thread-2 pool-1-thread-3

这种优化是重要的,因为创建一个新的线程是一个资源大量的操作。

任何使用LockSupport.Park方法将当前未执行任务的线程置于等待模式。

当所有线程忙于执行任务时,其他提交的任务将放入阻塞队列,等待线程变为可用状态。

所以要回答你的问题,线程只在任务第一次提交时才开始运行。

该信息对于JDK 7是正确的。我没有检查过其他实现。

+0

我认为这个答案会受益于一些参考或支持细节。 (该行为是否在某处指定?是否在所有JDK实现中都是如此?) – ruakh

+0

@Gray:我不明白您的意见。您是否说过您查看了特定JDK实现的源代码并确认了vstrom编码器的解释准确地描述了该实现的行为?如果是这样,那么请考虑编辑答案以表明您已经确认它是正确的特定JDK实现(并指向相关代码的链接)。 – ruakh

+0

是的,我有@ruakh。例如,任何sun开发工具包都有src.zip。可以从这里获得openjdk源代码:http://download.java.net/openjdk/jdk8/不幸的是,这些代码都不可链接。 – Gray