1、线程启动时机
根据您的问题,关于 ThreadPoolExecutor 中线程的启动时机:
-
线程创建与启动时机
- 线程在首次调用
executor.submit()时创建并启动 - 当提交第一个
Callable任务时,线程池会创建第一个工作线程 - 在代码中,这对应于
executor.submit(() -> {...})这一行执行时
- 线程在首次调用
-
具体执行流程
- 调用
submit()方法时,触发ThreadPoolExecutor的执行机制 - 检查当前线程数是否小于核心线程数(corePoolSize = 2)
- 如果小于,则调用
ThreadFactory.newThread()创建新线程 - 创建的线程会立即启动(start),执行提交的任务
- 调用
-
线程生命周期
- 线程一旦启动,会执行分配给它的任务
- 任务执行完毕后,线程不会终止,而是回到线程池中等待下一个任务
- 当线程空闲时间超过
keepAliveTime(60秒)且不是核心线程时才会被终止
所以,线程的启动时机是在调用 executor.submit() 提交任务的时候。
private boolean addWorker(Runnable firstTask, boolean core) {
w = new Worker(firstTask);
final Thread t = w.thread;
workers.add(w);
t.start();
}
worker作为线程的构造参数。
启动线程就是执行的woker的run方法。
private final class Worker
extends AbstractQueuedSynchronizer
implements Runnable
{
/**
* This class will never be serialized, but we provide a
* serialVersionUID to suppress a javac warning.
*/
private static final long serialVersionUID = 6138294804551838833L;
/** Thread this worker is running in. Null if factory fails. */
final Thread thread;
/** Initial task to run. Possibly null. */
Runnable firstTask;
/** Per-thread task counter */
volatile long completedTasks;
/**
* Creates with given first task and thread from ThreadFactory.
* @param firstTask the first task (null if none)
*/
Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
}
/** Delegates main run loop to outer runWorker */
public void run() {
runWorker(this);
}
在runWorker方法中执行futureTask的run方法,
如果是同步等待,futureTask.get()方法被执行,
执行完毕后在finishCompletion方法中唤醒等待在futureTask实例的线程。
private void finishCompletion() {
LockSupport.unpark(t);
}
futureTask.get()方法被执行会导致线程被挂起;
public V get() throws InterruptedException, ExecutionException {
LockSupport.park(this);
}
2万+

被折叠的 条评论
为什么被折叠?



