Android线程池来自Java的Executor接口,真正实现类是ThreadPoolExecutor。AsyncTask、OkHttp等中都涉及到线程池的配置因此线程池的配置十分重要。
ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, defaultHandler);
}
corePoolSize
线程池的核心线程数,默认情况下核心线程会一直存活,即使处于空闲状态。(当设置ThreadPoolExecutor的allowCoreThreadTimeOut为TRUE,核心线程也会设置超时策略,当等待新线程时间超过keepAliveTime,核心线程也会被停止)
maximumPoolSize
线程池容纳的最大线程数(包括核心线程数在内)
keepAliveTime
空闲线程存活时间,默认值作用于非核心线程。当设置ThreadPoolExecutor的allowCoreThreadTimeOut为TRUE,也会作用于核心线程)
unit
keepAliveTime的时间单位
workQueue
线程池中任务队列,用来存储线程池通过execute方法提交的Runnable
threadFactory
线程工厂,用来给线程池提供新线程。ThreadFactory是一个接口,只有一个创建Thread的方法:Thread newThread(Runnable r)
ThreadPoolExecutor执行任务逻辑
- 如果线程池数量未达到核心线程数,直接启动一个核心线程处理任务
- 线程数已达到核心线程,任务存储在任务队列中等待。
- 任务队列已满,来新任务则启动一个非核心线程开始是处理任务。(队列里第一条任务出队,新任务入队)
- 如果线程数未达到最大容纳线程数,则重复3,如果已经达到最大线程容纳数,ThreadPoolExecutor会调用RejectedExecutionHandler的rejectedExecution来抛出异常。
Executors提供的几种常用线程池
Executors提供了一组静态方法来创建一些常见线程池,实际上背后都是通过配置ThreadPoolExecutor来实现的。下面分析几种常见的线程池。
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
FixedThreadPool
通过Executors.newFixedThreadPool(nThreads)
new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
固定线程池的核心线程数和最大线程数设置为相同的,存活时间为 0,队列容量为Integer.MAX_VALUE。可以看到固定线程池来一个任务就会启动一个线程,当线程数达到设定之后放在队列里等待。
SingleThreadExecutor
通过Executors.newSingleThreadExecutor()
创建。
new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>())
单个线程池的配置是通过指定核心线程和最大线程数都为1来实现的。
CachedThreadPool
通过Executors.newCachedThreadPool()
创建。
new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>())
CachedThreadPool是线程数量不固定的线程池,由于指定最大线程数为Integer.MAX_VALUE,基本相当于无限制。SynchronousQueue是一种特殊的队列,可以简单理解为无法存储元素的队列,因此每来一个任务就会创建一个新线程。
ScheduledThreadPool
通过Executors.newScheduledThreadPool()
创建。
public static ScheduledExecutorService newScheduledThreadPool(
int corePoolSize, ThreadFactory threadFactory) {
return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
}
public ScheduledThreadPoolExecutor(int corePoolSize,
ThreadFactory threadFactory) {
super(corePoolSize, Integer.MAX_VALUE,
DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
new DelayedWorkQueue(), threadFactory);
}
ScheduledThreadPool是一种核心线程固定,非核心线程不限制的线程池,主用用来执行定时任务或周期任务。
ScheduledExecutorService的schedule方法。
public ScheduledFuture<?> schedule(Runnable command,
long delay, TimeUnit unit);
参考《Android 开发艺术探索》
来源:CSDN
作者:momo_ibeike
链接:https://blog.csdn.net/momo_ibeike/article/details/78223476