闲来没事突然想到这个问题,便百度了下想查看具体实现,无果。便自己翻看了下源码,以下是分析过程。
众所周知,Java内部自带了个线程池实现 ExecutorService (虽然一直被人看不起)。随便找到其中的一个静态方法
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
可知 ExecutorService 也只是一个封装,真正的实现还得看 ThreadPoolExecutor。根据推断我们可以首先从 `ThreadPoolExecutor#execute` 找起
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
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);
}
读题解,传入的 Runnable 实例最终经过一系列安全检验被传入 addWorker 方法中,继续追踪可以看到实例(firstTask) 被传入 `ThreadPoolLocal#Worker#init` 的有参构造器中,而该 Worker 实例被添加进名为 workers 的哈希表中
终于是找到正主了!让我们看看这个 Worker 到底是何方神圣,究竟是如何实现线程复用!
private final class Worker extends AbstractQueuedSynchronizer implements Runnable {
public void run() {
runWorker(this);
}
}
好家伙,原来 Worker 也实现了 Runnable,查看 runWorker 方法可知,当当前任务执行后task置空,Worker 线程调用 getTask 方法从任务队列中获取新任务并执行。至此便实现了一个 Worker 线程执行多个 Runnable 任务的功能。