线程池
优点
- 重用线程池中的线程,避免线程的创建销毁带来的性能开销。
- 控制线程池的最大并发数。
- 对线程简单管理:如定时执行以及指定间隔循环执行。
实现
ThreadPoolExecutor
方法是线程池的真正实现,下面是它的一个比较常用的构造方法:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue
ThreadFactory threadFactory)
corePoolSize
线程池的核心线程数,默认一直存活,即使没有使用。allowCoreThreadTimeOut属性为true时,当等待时间超
过keepAliveTime所指定的时长后,闲置的核心线程也会被终止。maximumPoolSize
线程池所能容纳的最大线程数,非核心线程数 = maximumPoolSize - corePoolSize。keepAliveTime
非核心线程数闲置超过这个时长,就会被回收。unit
指定keepAliveTime的时间单位,常用TimeUnit.MILLISECONDS,SECONDS,MINUTES等。workQueue
线程池任务队列,通过线程池的execute方法提交的Runnable对象会存储在这里。threadFactory
线程工厂,提供创建新线程的功能,只有Thread newThread(Runnable r)一个方法。如:
private static final ThreadFactory sThreadFactory = new ThreadFactory() {
private final AtomicInteger mCount = new AtomicInteger(1);
public Thread newThread(Runnable r) {
return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
}
};
执行规则
- 核心线程没用完时,直接启动核心线程
- 核心线程已经用完,任务会被插入到任务队列排队。
- 队列已满时,如果线程数量未达到线程池规定的最大值,就启动一个非核心线程
- 队列已满时,且线程数量达到线程池规定的最大值,就拒绝执行任务,调用RejectedExecutionHandler的
rejectedExecution方法通知调用者,默认直接抛出RejectedExecutionException
。
常用的4类线程池
FixedThreadPool
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
线程数量固定,只有核心线程,且空闲线程不会被回收,任务队列没有大小限制。
Runnable command = new Runnable() { @Override public void run() { SystemClock.sleep(2000); } }; ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4); fixedThreadPool.execute(command);
CachedThreadPool
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
只有非核心线程,线程数量为Integer.MAX_VALUE,空闲线程有60s的超时时长,任务队列相当于空集合,导致
任何任务都会立即被执行。扫描二维码关注公众号,回复: 1502703 查看本文章ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); cachedThreadPool.execute(command);
ScheduledThreadPool
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { return new ScheduledThreadPoolExecutor(corePoolSize); } public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, Integer.MAX_VALUE, DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS, new DelayedWorkQueue()); }
核心线程数量固定,非核心线程数量不限,非核心线程一空闲就会立即回收,主要用于执行定时任务和固定周
期的重复任务。ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(4); // 2000ms后执行command scheduledExecutorService.schedule(command, 2000, TimeUnit.MILLISECONDS); // 延迟10ms后,每隔1000ms执行一次command scheduledExecutorService.sche·duleAtFixedRate(command, 10, 1000, TimeUnit.MILLISECONDS);
SingleThreadExecutor
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
只有一个核心线程,没有非核心线程,任务队列没有大小限制,确保所有任务都在同一线程中按顺序执行。
ExecutorService singleThreadExcutor = Executors.newSingleThreadExecutor(); singleThreadExcutor.execute(command);
参考资料
[1] 《Android开发艺术探索》, 任玉刚. https://book.douban.com/subject/26599538/