很显然,线程池的代码有几个问题:
exec 初始化的时候,线程池内部有多少线程?如果线程池内部线程本身比较少,循环时候,线程池也会通过 new Thread 线程的方式为线程池补充线程。
也是最重要的一点,for 循环中每次都 exec.shutdown(),调用该方法的意思是关闭当前线程池。线程池本身并不需要关闭。更不应该在 for 循环中关闭。
/**
* Initiates an orderly shutdown in which previously submitted
* tasks are executed, but no new tasks will be accepted.
* Invocation has no additional effect if already shut down.
*
*
This method does not wait for previously submitted tasks to
* complete execution. Use {@link #awaitTermination awaitTermination}
* to do that.
*
* @throws SecurityException {@inheritDoc}
*/
public void shutdown() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
checkShutdownAccess();
advanceRunState(SHUTDOWN);
interruptIdleWorkers();
onShutdown(); // hook for ScheduledThreadPoolExecutor
} finally {
mainLock.unlock();
}
tryTerminate();
}
查看 shutdown 源码,可以看到 shutdown 后,线程池不再接受新任务。
也就是第一次 for 循环,线程池增加了一个任务。然后调用 shutdown 后,线程池就不再接受新的任务了。
意思是说:线程池的代码其实只有一个线程在处理任务,而上面的 new Thread 代码却有多个线程在处理。
当然是上面的代码处理的快。