public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
由于调用的ThreadPoolExecutor的构造方法的核心池大小和最大线程池均为1,所以该线程池只能存在一个线程。
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
我们可以看到,该创建线程池的方法提供了一个课传递的参数nThreads
,该参数可以设置线程池的核心大小以及最大容量,即该线程池的固定大小。
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
我们可以看到,这里的最大线程大小可以达到Integer
的最大大小2147483647
,一般情况下我们是用不了这么多线程的,想用这么多的线程,是需要强大的硬件设备的支持,我们可以看到在线程被创建后60s如果没有被调用就会被释放,关于这些参数我会在后面讲到。
这几种方式创建的线程池都是通过创建ThreadPoolExecutor对象来实现的
我们来看一下这三个线程池创建时调用的ThreadPoolExecutor的构造方法
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
我们看下这里面调用的this方法
public ThreadPoolExecutor(int corePoolSize, // 核心线程池大小
int maximumPoolSize, // 最大线程池大小
long keepAliveTime, // 超时了没有人调用就会释放
TimeUnit unit, // 超时单位
BlockingQueue<Runnable> workQueue, // 阻塞队列
ThreadFactory threadFactory, // 线程工厂,创建线程线程的
RejectedExecutionHandler handler) {// 拒绝策略
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
所以我们看到这些方法本质上都是调用了ThreadPoolExecutor的构造方法
注意:虽然用Executors创建线程池可以方便我们的操作,但是阿里发布的 Java开发手册中强制线程池不允许使用 Executors 去创建,所以建议大家还是用ThreadPoolExecutor 来创建线程池
ThreadPoolExecutor创建线程池参考https://blog.csdn.net/jjj___jjj/article/details/105314542