线程池笔记

线程池的好处是:

  • 减避免因为线程频繁创建与销毁带来的开销
  • 能有效控制线程池的最大并发数,避免大量的进程因为互相抢占资源而陷入阻塞
  • 能够对线程进行简单的管理,并提供定时执行及指定循环间隔执行等功能
Android中的线程池是来自Java的Executor,这是一个接口,真正的实现类是ThreadPoolExecutor,常用的构造方法如下:
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)

参数含义:
  • corePoolSize:线程池的核心线程的数量,默认情况下,核心线程会一直存活。如果设置了allowCoreThreadTimeOut为True,那么闲置的核心线程在keepAliveTime的时长之后将会被终止。
  • maximumPoolSize:最大线程数量。当线程池的线程数量达到最大值之后,之后的新任务将会被阻塞
  • keepAliveTime:闲置的非核心线程最大存活时间,超过这个时长,就会被回收。
  • unit:时长的单位
  • workQueue:线程池中的任务队列,通过线程池的execute方法提交的Runnable对象会存储在这个参数之中
  • threadFacory:线程工厂,为线程提供创建新线程的功能
ThreadPoolExecutor执行任务时遵循的原则:
  1. 核心线程未满,启动新的核心线程执行任务
  2. 核心线程已满,任务会被插入到任务队列中等待执行
  3. 如果无法插入到队列,往往是由于队列已满,如果线程数量未达到最大值,会启动一个新的非核心线程来执行任务
  4. 如果达到了线程池的最大线程数,那么会拒绝执行新任务,ThreadPoolExecutor会调用RejectedExecutionHandler的rejectedExecution方法通知调用者。
四类线程池:
  1. FixedThreadPool:
    public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()); }

    从传入的参数可以看出来该线程池全都是核心线程,且不会被回收,所以可以快速响应外界的请求。任务队列的大小也是没有限制的。
  2. CachedThreadPool
    public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue()); }

    没有核心线程,线程数量无限,60s就回收闲置的线程。
    适用于执行大量的耗时较少的任务。
  3. ScheduleThreadPool
    public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedWorkQueue()); }

    核心线程数量固定,非核心线程数量不限,一旦空闲就会被回收。
  4. SingleThreadExecutor
    public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue())); }

    【线程池笔记】整个线程池只有一个线程,能确保所有的任务都在同一个线程中顺序执行,使得任务之间不需处理线程同步的问题。

    推荐阅读