线程池的好处是:
- 减避免因为线程频繁创建与销毁带来的开销
- 能有效控制线程池的最大并发数,避免大量的进程因为互相抢占资源而陷入阻塞
- 能够对线程进行简单的管理,并提供定时执行及指定循环间隔执行等功能
Android中的线程池是来自Java的Executor,这是一个接口,真正的实现类是ThreadPoolExecutor,常用的构造方法如下:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
参数含义:
- corePoolSize:线程池的核心线程的数量,默认情况下,核心线程会一直存活。如果设置了allowCoreThreadTimeOut为True,那么闲置的核心线程在keepAliveTime的时长之后将会被终止。
- maximumPoolSize:最大线程数量。当线程池的线程数量达到最大值之后,之后的新任务将会被阻塞
- keepAliveTime:闲置的非核心线程最大存活时间,超过这个时长,就会被回收。
- unit:时长的单位
- workQueue:线程池中的任务队列,通过线程池的execute方法提交的Runnable对象会存储在这个参数之中
- threadFacory:线程工厂,为线程提供创建新线程的功能
ThreadPoolExecutor执行任务时遵循的原则:
- 核心线程未满,启动新的核心线程执行任务
- 核心线程已满,任务会被插入到任务队列中等待执行
- 如果无法插入到队列,往往是由于队列已满,如果线程数量未达到最大值,会启动一个新的非核心线程来执行任务
- 如果达到了线程池的最大线程数,那么会拒绝执行新任务,ThreadPoolExecutor会调用RejectedExecutionHandler的rejectedExecution方法通知调用者。
四类线程池:
-
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>()); }
没有核心线程,线程数量无限,60s就回收闲置的线程。
适用于执行大量的耗时较少的任务。
-
ScheduleThreadPool
public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedWorkQueue()); }
核心线程数量固定,非核心线程数量不限,一旦空闲就会被回收。
-
SingleThreadExecutor
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
整个线程池只有一个线程,能确保所有的任务都在同一个线程中顺序执行,使得任务之间不需处理线程同步的问题。
网友评论