核心线程会一直存活,即使它们处于闲置状态。非核心线程闲置超过超时时长会被回收。
一、线程池优点
1.重用线程,避免线程创建和销毁带来的开销。
2.有效控制线程池最大并发数,避免大量线程因互相抢占系统资源导致阻塞。
3.方便管理,提供定时执行和间隔循环执行。
二、ThreadPoolExecutor
android线程池概念来源于java的Executor接口,真正的实现是ThreadPoolExecutor。android四种线程池就是通过配置ThreadPoolExecutor来实现的。常见构造方法如下:
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,
TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory)
- corePoolSize
线程池的核心线程数。默认情况下,核心线程会一直存活,即使它们处于闲置状态。 - maximumPoolSize
线程池中可容纳的最大线程数。当活动线程达到这个数目后,后续新任务被阻塞。 - keepAliveTime
非核心线程闲置时的超时时长,超过此时长,会被回收。当ThreadPoolExecutor的allowCoreThreadTimeout设置为true时,keepAliveTime同样会作用于核心线程。 - unit
指定keepAliveTime的时间位。常见枚举常量有TimeUnit.MILLISECONDS、TimeUnit.SECONDS、TimeUnit.MINUTES - BlockingQueue<Runnable> workQueue
线程池中的任务队列 - ThreadFactory threadFactory
线程工厂,为线程池创建新线程。
三、分析各种线程池
AsyncTask 源代码略
核心线程数等于CPU核心数+1
最大线程数等于CPU核心数*2+1
默认情况下核心线程会在线程池中一直存活,即使它们处于闲置状态
非核心线程通过keepAliveTime设置闲置时长,超时会被回收。
任务队列容量128:new LinkedBlockingQueue<Runnable>(128);
FixedThreadPool
只有核心线程,并且没有超时机制,任务队列没有大小限制。
它能快速地响应外界的请求。
public static ExecutorService newFixedThreadPool(int nThreads){
return new ThreadPoolExecutor(nThreads,nThreads,0L,
TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
}
- CachedThreadPool
public static ExecutorService newCachedThreadPool(){
return new ThreadPoolExecutor(0,Integer.MAX_VALUE,60L,
TimeUnit.SECONDS,new SynchronousQueue<Runnable>());
}
只有非核心线程,并且数量不限。空闲线程超时时长60秒。
比较适合执行大量耗时较少的任务。当整个线程池处于闲置状态时,都会超时被停止,几乎不会占用任何系统资源。
- ScheduledThreadPool
public static ExecutorService newScheduledThreadPool(int corePoolSize){
return new ThreadPoolExecutor(corePoolSize,Integer.MAX_VALUE,0L,
TimeUnit.SECONDS,new DelayedWorkQueue<Runnable>());
}
核心线程数量固定的,非核心线程数没有限制。主要用于执行定时任务和具有固定周期的重复任务。
- SingleThreadExecutor
public static ExecutorService newSingleThreadExecutor(){
return new ThreadPoolExecutor(1,1,0L,
TimeUnit.SECONDS,new LinkedBlockingQueue<Runnable>());
}
只有一个核心线程,统一所有外界任务到一个线程中,使得这些任务间不需要处理线程同步的问题。