ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
#### 11.3.1 ThreadPoolExecutor [ThreadPoolExecutor](https://www.androidos.net.cn/android/6.0.1_r16/xref/libcore/luni/src/main/java/java/util/concurrent/ThreadPoolExecutor.java)是线程池的真正实现,它的构造方法提供了一系列参数来配置线程池,下面介绍ThreadPoolExecutor的构造方法中各个参数的含义,这些参数将会直接影响到线程池的功能特性,下面是ThreadPoolExecutor的一个比较常用的构造方法。 ``` public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) ``` * **corePoolSize** **线程池的核心线程数,默认情况下,核心线程会在线程池中一直存活,即使它们处于闲置状态**。*如果将ThreadPoolExecutor的[allowCoreThreadTimeOut](https://developer.android.google.cn/reference/kotlin/java/util/concurrent/ThreadPoolExecutor?hl=en#allowsCoreThreadTimeOut())属性设置为true,那么闲置的核心线程在等待新任务到来时会有超时策略,这个时间间隔由keepAliveTime所指定,当等待时间超过keepAliveTime所指定的时长后,核心线程就会被终止*。 * **maximumPoolSize** **线程池所能容纳的最大线程数,当活动线程数达到这个数值后,后续的新任务将会被阻塞**。 * **keepAliveTime** **非核心线程闲置时的超时时长,超过这个时长,非核心线程就会被回收**。当ThreadPool-Executor的**allowCoreThreadTimeOut属性设置为true时,keepAliveTime同样会作用于核心线程**。 * **unit** **用于指定keepAliveTime参数的时间单位**,这是一个枚举,常用的有TimeUnit. MILLISECONDS(毫秒)、TimeUnit.SECONDS(秒)以及TimeUnit.MINUTES(分钟)等。 * **workQueue** **线程池中的任务队列,通过线程池的execute方法提交的Runnable对象会存储在这个参数中**。 * **threadFactory** **线程工厂,为线程池提供创建新线程的功能**。 **ThreadFactory是一个接口,它只有一个方法**:`Thread newThread(Runnable r)`。 除了上面的这些主要参数外,ThreadPoolExecutor**还有一个不常用的参数RejectedExecutionHandler handler**。**当线程池无法执行新任务时,这可能是由于任务队列已满或者是无法成功执行任务,这个时候ThreadPoolExecutor会调用`RejectedExecutionHandle`r的rejectedExecution方法来通知调用者,默认情况下rejectedExecution方法会直接抛出一个RejectedExecutionException**。 ``` public interface RejectedExecutionHandler { void rejectedExecution(Runnable r, ThreadPoolExecutor executor); } private static final RejectedExecutionHandler defaultHandler =new AbortPolicy(); ``` :-: ![](https://img.kancloud.cn/29/45/29452a0b3876ef068d07e4aef1244341_473x114.png) RejectedExecutionHandler的树结构 >[success]注意:从源码和树结构中可以看出,这个RejectedExecutionHandler是一个接口,但它并不是handler,只是名字里有handler,在ThreadPoolExecutor这个类里面,它有**CallerRunsPolicy**、**AbortPolicy**、**DiscardPolicy**和**DiscardOldestPolicy**四个实现类。 **ThreadPoolExecutor为`RejectedExecutionHandler`提供了几个可选值**:**CallerRunsPolicy**、**AbortPolicy**、**DiscardPolicy**和**DiscardOldestPolicy**,其中**AbortPolicy是默认值(源码中可以看出),它会直接抛出RejectedExecutionException**,由于`RejectedExecutionHandler`这个参数不常用,这里就不再具体介绍了。 ThreadPoolExecutor执行任务时大致遵循如下规则: * (1)**如果线程池中的线程数量未达到核心线程的数量,那么会直接启动一个核心线程来执行任务**。 * (2)**如果线程池中的线程数量已经达到或者超过核心线程的数量,那么任务会被插入到任务队列中排队等待执行**。 * (3)**如果在步骤2中无法将任务插入到任务队列中,这往往是由于任务队列已满,这个时候如果线程数量未达到线程池规定的最大值,那么会立刻启动一个非核心线程来执行任务**。 * (4)**如果步骤3中线程数量已经达到线程池规定的最大值,那么就拒绝执行此任务,ThreadPoolExecutor会调用RejectedExecutionHandler的rejectedExecution方法来通知调用者**。 ThreadPoolExecutor的参数配置在AsyncTask中有明显的体现,下面是**AsyncTask中的线程池的配置情况**: ``` private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); private static final int CORE_POOL_SIZE = CPU_COUNT + 1; private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; private static final int KEEP_ALIVE = 1; private static final ThreadFactory sThreadFactory = new ThreadFactory() { private final AtomicInteger mCount = new AtomicInteger(1); public Thread newThread(Runnable r) { return new Thread(r, "AsyncTask #" + mCount.getAndIncrement()); } }; private static final BlockingQueue<Runnable> sPoolWorkQueue = new LinkedBlockingQueue<Runnable>(128); /** * An {@link Executor} that can be used to execute tasks in parallel. */ public static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory); ``` 从上面的代码可以知道,AsyncTask对`THREAD_POOL_EXECUTOR`这个线程池**进行了配置**,配置后的线程池规格如下: * · **核心线程数等于CPU核心数 + 1**; * · **线程池的最大线程数为CPU核心数的2倍 + 1**; * · **核心线程无超时机制,非核心线程在闲置时的超时时间为1秒**; * · **任务队列的容量为128**。