前言

上节讲了讲自定义线程池,今天我们来聊聊线程池框架,在实际开发中我们还是基本使用线程框架Executor给我们提供的一些工具类,Java提供的Executor都在JUC(java.util.concurrent)包下面,主要包括:线程池工厂类Executors,线程池实现类ThreadPoolExecutor等,今天呢我们主要聊聊Executors,看看通过Executors我们可以做什么?OK,不多说废话,我们马上进入今天的主题,让我们扬帆起航,开启今天的并发之旅吧。

什么是Executors?

Executors,扮演的是线程工厂的角色,一定要与Executor相区分开,Executors只是Executor框架中的一个工厂类而已,通过Executors我们可以创建特定功能的线程池(ThreadPoolExecutor),通过这句话你是不是对Executors和ThreadPoolExecutor的关系有了一定的认识,这两个都是Executor框架中的一部分(关于Executor框架的各个成员组成这里就先不做说明,今天主要是学会怎么使用线程工厂创建线程池)。

如何使用Executors?

线程池ThreadPoolExecutor通常都是通过Executors来创建的,我们可以根据自己的需求创建下面几种不同作用的线程池:

// 创建一个固定数量的线程池ExecutorService ExecutorService1 = Executors.newFixedThreadPool(10);
// 返回一个可根据实际情况调整线程个数的线程池ExecutorService ExecutorService2 = Executors.newCachedThreadPool();
// 创建一个线程数量为1的线程池ExecutorService ExecutorService3 = Executors.newSingleThreadExecutor();
// 返回一个ScheduledExecutorService对象,该对象也是调用父类的线程池方法,类似newFixedThreadPoolScheduledExecutorService ScheduledExecutorService = Executors.newScheduledThreadPool(5);

线程池的使用之前讲自定义线程池已经说过了,主要也就是:execute向线程池提交任务

shutdown和shutdownNow关闭线程池

本文由“壹伴编辑器”提供技术支持

newFixedThreadPool:该方法返回一个固定数量的线程池,该方法的线程数量始终不变,当有任务提交时,若线程池中有空闲线程,则立即执行,若没有,则会被缓存在一个任务队列中等待有空闲的线程再去执行;(核心线程数等于最大线程数,默认空闲时间为0,空闲立马销毁),该方法有2个实现,我们看下面源码:

public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue());
}
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue(),
threadFactory);
}

再分别看下这2个方法在线程池中的实现:

// 我们会发现没有传入线程工厂的方法调用了一个默认的线程工厂public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
// 而有传入线程工厂的方法调用自己传入的线程工厂public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue,
ThreadFactory threadFactory) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, defaultHandler);
}

本文由“壹伴编辑器”提供技术支持

newSingleThreadExecutor:创建一个线程数量为1的线程池,若空闲则执行,否则入队列等待被执行;(核心线程数量为1,最大线程数量也为1,空闲等待时间为0),该方法也有2个实现,一个带自定义的线程工厂,一个不带:

public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue()));
}
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue(),
threadFactory));
}

本文由“壹伴编辑器”提供技术支持

newCachedThreadPool:返回一个可根据实际情况调整线程个数的线程池,不限制最大线程数量,若有任务则没线程时则创建线程,每个线程空闲等待时间为60秒,60秒后如果该线程没有任务可执行,则被回收;(核心线程数量为0,最大线程数量为最大,空闲等待时间为60s)

public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue());
}
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue(),
threadFactory);
}

本文由“壹伴编辑器”提供技术支持

newScheduledThreadPool:返回一个ScheduledExecutorService对象,该线程池可以指定线程数量

// 返回一个ScheduledExecutorService对象public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
// 调了父类super的方法里面还是一个ThreadPoolExecutorpublic ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
new DelayedWorkQueue());
}
// 父类super中的ThreadPoolExecutorpublic ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}