线程池中的实际线程创建
Actual thread creation in thread pool
如果我有一个固定大小的线程池,它什么时候真正调用 Thread.start()
来启动线程? (它会在创建时启动它们吗?还是等到我开始提交任务时才启动?)
如果像这样创建固定大小的线程池:
ExecutorService es = Executors.newFixedThreadPool(5);
最初没有创建线程。当您提交第一个任务时,只会创建一个线程(它被命名为 "pool-1-thread-1"。
对于每个额外提交的任务,都会创建一个新线程,直到达到指定的固定大小(本例中为 5),即使这些任务实际上 运行 并不是并行的。
例如,如果您只提交 3 个任务,则只会创建 3 个具有以下名称的线程:
pool-1-thread-1
pool-1-thread-2
pool-1-thread-3
此优化很重要,因为创建新线程是一项 resource-heavy 操作。
使用 LockSupport.Park
方法将当前未执行任务的任何线程置于等待模式。
当所有线程都忙于执行任务时,额外提交的任务将被放入阻塞队列,等待线程可用。
因此,为了回答您的问题,线程仅在首次提交任务时 运行 启动。
此信息适用于JDK 7。我还没有检查其他实现。
如果我有一个固定大小的线程池,它什么时候真正调用 Thread.start()
来启动线程? (它会在创建时启动它们吗?还是等到我开始提交任务时才启动?)
如果像这样创建固定大小的线程池:
ExecutorService es = Executors.newFixedThreadPool(5);
最初没有创建线程。当您提交第一个任务时,只会创建一个线程(它被命名为 "pool-1-thread-1"。
对于每个额外提交的任务,都会创建一个新线程,直到达到指定的固定大小(本例中为 5),即使这些任务实际上 运行 并不是并行的。
例如,如果您只提交 3 个任务,则只会创建 3 个具有以下名称的线程:
pool-1-thread-1
pool-1-thread-2
pool-1-thread-3
此优化很重要,因为创建新线程是一项 resource-heavy 操作。
使用 LockSupport.Park
方法将当前未执行任务的任何线程置于等待模式。
当所有线程都忙于执行任务时,额外提交的任务将被放入阻塞队列,等待线程可用。
因此,为了回答您的问题,线程仅在首次提交任务时 运行 启动。
此信息适用于JDK 7。我还没有检查其他实现。