针对android中的多线程请求,本文主要介绍 android中线程池的基本使用。
1:线程池的分类
FixedThreadPool:它是一种线程数量固定的线程池,当线程处于空闲状态时,它们并不会被回收,除非线程池被关闭,当所有的线程都处于活动状态时,新任务都会处于等待状态,直到有线程空闲出来。该线程池中只有核心线程,并且这些核心线程不会被回收,这意味着它能够更加快速的响应外界的请求。
CachedThreadPool: 该线程池中线程数量不固定,并且内部只有非核心线程,其线程的最大值为 Integer.MAX_VALUE。所以可以认为该线程池中的线程数量可以任意大。该线程池的特定是当线程池中的线程都处于活动状态时,线程池会创建新的线程来处理新的任务,否则就会利用空闲的线程来处理新的任务。该线程池中的空闲线程都有超时机制,这个超时时长为 60s ,超过60s 空闲线程就会被回收。 ScheduledThreadPool: 该线程池中包含核心线程以及非核心线程,核心线程数量是固定的,而非核心线程数量是没有限制的,并且当非核心线程闲置时会被立即回收。 SingleThreadExecutor:该线程池是一个单例线程,其内部只有一个核心线程。2:线程池的基本使用
FixedThreadPool:
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4)fixedThreadPool.execute(runnable)复制代码
CachedThreadPool:
ExecutorService cacheThreadPool = Executors.newCachedThreadPool() cacheThreadPool.execute(runnable)复制代码
ScheduledThreadPool:
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(4) scheduledThreadPool.schedule(runnable3, 2000, TimeUnit.MILLISECONDS)复制代码
SingleThreadExecutor:
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor()singleThreadExecutor.execute(runnable)复制代码
2:线程池的基本使用
FixedThreadPool:
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4)fixedThreadPool.execute(runnable)复制代码
CachedThreadPool:
ExecutorService cacheThreadPool = Executors.newCachedThreadPool() cacheThreadPool.execute(runnable)复制代码
ScheduledThreadPool:
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(4) scheduledThreadPool.schedule(runnable3, 2000, TimeUnit.MILLISECONDS)复制代码
SingleThreadExecutor:
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor()singleThreadExecutor.execute(runnable)复制代码
3: 线程池构造解析
android中线程池概念来源于java中的Executor,而Executor通过源码我们可以看出是一个接口;
public interface Executor { void execute(Runnable command);}复制代码
内部只包含一个抽象方法 execute(….);
同时android中 重新定义了ExecutorService接口去继承上述接口;
public interface ExecutorService extends Executor{}复制代码
而 ExecutorService 接口的实现类是:
public abstract class AbstractExecutorService implements ExecutorService{}复制代码
抽象类AbstractExecutorService 的具体实现是:
public class ThreadPoolExecutor extends AbstractExecutorService{}复制代码
通过上述关系可以看到线程池的真正实现为ThreadPoolExecutor,在ThreadPoolExecutor 中提供了一系列的参数来创建不同的线程池。
下面我们来看ThreadPoolExecutor的构造函数:public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {}复制代码
内部参数:
corePoolSize:线程的核心线程数;
maximumPoolSize:线程池所能容纳的最大线程数: keepAliveTime:非核心线程闲置时的超时市场,超过这个时长非核心线程就会被回收 unit:用于指定keepAliveTime 的单位 workQueue:线程池中的任务队列 threadFactory:线程工厂,为线程池提供创建新线程的功能 handler:当线程池无法执行新的任务时,会调用handler的rejectedEcexutor方法来通知调用者。该参数不常用,可以忽略。 通过源码我们可以看到google是通过工厂方式去创建各种线程池,具体源码我们可以通过public class Executors{}复制代码
该类可以看到内部通过各种方法去获取不同的线程池。
下面我们根据Executors 中各个方法去看各个线程池是如何实现的。
FixedThreadPool:
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()); }复制代码
FixedThreadPool 通过调用 ThreadPoolExecutor构造函数 可以看出实质上是通过外部设置了 核心线程数,以及非核心线程数。
CachedThreadPool:public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue()); }复制代码
CachedThreadPool 内部可以看出实质上 核心线程数为0 ,而非核心线程数为Int最大值
SingleThreadExecutor:public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue())); }复制代码
SingleThreadExecutor 可以看出实质上是核心线程数以及非核心线程数均为1;
ScheduledThreadPool:
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { return new ScheduledThreadPoolExecutor(corePoolSize); }public class ScheduledThreadPoolExecutor extends ThreadPoolExecutor implements ScheduledExecutorService { .... public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, Integer.MAX_VALUE, DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS, new DelayedWorkQueue()); } .... }复制代码
ScheduledThreadPool 可以看出核心线程数是通过外部设置,而非核心线程数实质是int的最大值。
4 : 线程池的基本执行流程
1:如果线程池中核心线程未达到上限那么,则会直接启动一个核心线程去执行任务;
2:如果核心线程达到上限,那么会将任务放到任务队列中,等待执行, 3:如果任务无法插入到任务队列中,则会开启一个非核心线程去执行任务, 4:如果线程池中的线程已经达到线程数量的上限,则将不会去执行任务,ThreadPoolExecutor将会调用RejectedExecutionHandler的rejectedExecution方法通知调用者。以下通过图示来说明: