java - Java ThreadPool 构造 - “何时创建线程”?
问题描述
成员们,我正在使用 ThreadPool 构造(ThreadPoolExecutors),而不是每次都实例化新线程。我的问题是:
- JVM 什么时候真正创建和启动新线程?
- JVM 如何将新的 Runnable 任务分配给已经启动的线程?
解决方案
JVM 什么时候真正创建并启动新线程?
这取决于您使用的框架。如果您使用ThreadPoolExecutor
的是自 1.5 以来位于 JDK 的那个,线程池是在第一个任务提交时创建的,而不是在创建时ThreadPoolExecutor
创建的。下面的代码片段来自java.util.concurrent.ThreadPoolExecutor
:
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
/*
* Proceed in 3 steps:
*
* 1. If fewer than corePoolSize threads are running, try to
* start a new thread with the given command as its first
* task. The call to addWorker atomically checks runState and
* workerCount, and so prevents false alarms that would add
* threads when it shouldn't, by returning false.
*
* 2. If a task can be successfully queued, then we still need
* to double-check whether we should have added a thread
* (because existing ones died since last checking) or that
* the pool shut down since entry into this method. So we
* recheck state and if necessary roll back the enqueuing if
* stopped, or start a new thread if there are none.
*
* 3. If we cannot queue task, then we try to add a new
* thread. If it fails, we know we are shut down or saturated
* and so reject the task.
*/
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}
JVM 如何将新的 Runnable 任务分配给已经启动的线程?
例如ThreadPoolExecutor
,它首先将任务放入workQueue
,它是 aBlockingQueue
并且在创建时ThreadPoolExecutor
创建,然后,当线程池中的一个工作线程完成最后一个任务时,它会尝试从workQueue
.
但请注意,所有的工人都是首先创建一个初始任务,他们在一次创建时完成工作。
private boolean addWorker(Runnable firstTask, boolean core) {
推荐阅读
- exchange-server - iCalUId 的最大长度
- ios - IOS 中 react-native 应用的输入建议
- bash - Bash - 如何替换重复的字符并在一行中只留下一个
- mysql - Node.js 防止在 setInterval 中堆叠异步函数
- visual-studio-code - Visual Studio 代码中是否有类似于“设置下一个语句”的内容?
- powershell - PowerShell 不会在另一台机器上运行批处理文件
- r - 使用 tidyr 将一列拆分为两列
- java - Jackson yaml 库无法解析有效的 yaml 文件
- ios - 如何在同一设备但不同帐户中执行ios IAP
- c++ - visual c++ /MANIFESTUAC 链接器选项不起作用