1.概述
线程在Android中是一个非常重要的概念,分为主线程和子线程,主线程主要负责与界面有关的操作,而子线程负责其他耗时的操作,不能将耗时操作放在主线程中,不然会引发ANR问题。
线程池可以看做是一个线程的集合,提供了简单的几种管理方法,使用线程池有几个好处:
- 线程复用,重用池中的线程避免过多的开销;
- 有效控制最大线程的数量,不会因为开启过多的线程而造成阻塞;
- 简单的管理,并能够设置定时执行和间隔循环执行等功能。
2.主要参数
ThreadPoolExecutor是线程池的真正实现,构造方法提供了一系列的参数设置
public ThreadPoolExecutor (int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
corePoolSize:核心线程数量,核心线程指的是即使线程池处于空闲状态,这些线程也不会被关闭,除非 allowCoreThreadTimeOut设置为true
maximumPoolSize:最大线程数量,线程池中允许的最大线程数。
keepAliveTime:线程空闲存活时间,当某一非核心线程空闲时,超过这个时间,会被自动回收,当allowCoreThreadTimeOut设置为true时,这个参数也会对核心线程起作用。
unit:超时时间单位;枚举量
workQueue:任务阻塞队列,当且仅当执行了execute()方法后,任务才会被放入该队列,然后按照既有的任务策略执行任务。
threadFactory:线程工厂,用来创建新的线程。
handler:任务由于某些原因被拒绝后的处理策略Handler。当任务队列已满或者任务无法执行时,这个时候RejectedExecutionHandler就会通知调用者。默认情况下,RejectedExecutionHandler会抛出一个RejectionExecutionException。该量可以通过方法setRejectedExecutionHandler()来设置。有一下几个之可以提供:
-
ThreadPoolExecutor.AbortPolicy:默认取值,直接抛出RejectionExecutionException;
-
ThreadPoolExecutor.CallerRunsPolicy:交给执行execute()方法的线程执行这个任务;如果线程池已经shudown,这个任务就会被抛弃;
-
ThreadPoolExecutor.DiscardOldestPolicy:抛弃之前的未被执行的任务,重新尝试execute()方法;如果线程池已经shudown,这个任务就会被抛弃;
-
ThreadPoolExecutor.DiscardPolicy:直接抛弃该任务。
线程池执行任务时大致遵循下列原则:
- 如果线程数量未达到最大核心数量,则直接开启一个核心线程执行任务;
- 如果线程数量已经达到或者超过最大核心线程,那么将该任务放入等待队列workQueue;
- 如果上一步中无法插入到等待队列,并且线程数量没有达到最大线程数,那么开启一个非核心线程来执行任务;
- 如果已经达到最大线程数,执行RejectionExectionHandler。
3.主要方法
一些set与get方法就不介绍了,这里主要介绍几个重要的。
public void allowCoreThreadTimeOut (boolean value):设置核心线程超时,如果设置为true,核心线程空闲时间超过keepAliveTime会被回收;
protected void beforeExecute (Thread t, Runnable r):线程池中执行任务之前运行的方法,主要用来记录搜集数据;
protected void afterExecute (Runnable r, Throwable t):执行任务之后运行的方法
public void purge ():移除等待队列中已经被cancel的任务;
4.线程分类
Android中常见的四类线程池具有不同的功能,通过对参数进行不同的配置来实现自己的功能特性。
(1)FixedThreadPool
通过执行Executors中的静态方法newFixedThreadPool方法来获得,它是一种固定线程数量的线程池,线程空闲也不会回收,除非线程关闭。当所有的线程都处于活动状态时,新任务会被放入等待队列,直到有线程空出。由于这些线程不会被收回,因此可以更加快速的响应外界的请求。实现如下:
(2)CachedThreadPool
通过执行Executors中的静态方法newCachedThreadPool方法来获得,其实现如下:
从实现方法来看,CachedThreadPool没有核心线程,线程数量没有限制,任何线程空闲超过60s就会被回收。该特性表明CachedThreadPool适合执行大量的耗时较少的任务。当没有任务执行时,其基本上不占资源。
(3)ScheduledThreadPool
通过执行Executors中的静态方法newScheduledThreadPool()获得,其实现如下
其核心线程数量固定,非核心线程没有限制,非核心线程空闲时立即回收,该线程池可以可以执行延时任务和周期性任务。
(4)SingleThreadScheduledExecutor
通过Executors中的静态方法newSingleThreadScheduledExecutor()获得,其实现如下:
核心线程数与最大线程数均为1,确保所有的任务都在同一个线程中运行,作用在与将外界所有的任务都放在同一个线程中,无需再考虑线程同步的问题。