Java线程池配置

余生颓废 提交于 2019-11-26 01:30:05

Android线程池来自Java的Executor接口,真正实现类是ThreadPoolExecutor。AsyncTask、OkHttp等中都涉及到线程池的配置因此线程池的配置十分重要。

ThreadPoolExecutor

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             threadFactory, defaultHandler);
    }

corePoolSize

线程池的核心线程数,默认情况下核心线程会一直存活,即使处于空闲状态。(当设置ThreadPoolExecutor的allowCoreThreadTimeOut为TRUE,核心线程也会设置超时策略,当等待新线程时间超过keepAliveTime,核心线程也会被停止)

maximumPoolSize

线程池容纳的最大线程数(包括核心线程数在内)

keepAliveTime

空闲线程存活时间,默认值作用于非核心线程。当设置ThreadPoolExecutor的allowCoreThreadTimeOut为TRUE,也会作用于核心线程)

unit

keepAliveTime的时间单位

workQueue

线程池中任务队列,用来存储线程池通过execute方法提交的Runnable

threadFactory

线程工厂,用来给线程池提供新线程。ThreadFactory是一个接口,只有一个创建Thread的方法:Thread newThread(Runnable r)

ThreadPoolExecutor执行任务逻辑

  1. 如果线程池数量未达到核心线程数,直接启动一个核心线程处理任务
  2. 线程数已达到核心线程,任务存储在任务队列中等待。
  3. 任务队列已满,来新任务则启动一个非核心线程开始是处理任务。(队列里第一条任务出队,新任务入队)
  4. 如果线程数未达到最大容纳线程数,则重复3,如果已经达到最大线程容纳数,ThreadPoolExecutor会调用RejectedExecutionHandler的rejectedExecution来抛出异常。

Executors提供的几种常用线程池

Executors提供了一组静态方法来创建一些常见线程池,实际上背后都是通过配置ThreadPoolExecutor来实现的。下面分析几种常见的线程池。

public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }

FixedThreadPool

通过Executors.newFixedThreadPool(nThreads)

new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());

固定线程池的核心线程数和最大线程数设置为相同的,存活时间为 0,队列容量为Integer.MAX_VALUE。可以看到固定线程池来一个任务就会启动一个线程,当线程数达到设定之后放在队列里等待。

SingleThreadExecutor

通过Executors.newSingleThreadExecutor()创建。

new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>())

单个线程池的配置是通过指定核心线程和最大线程数都为1来实现的。

CachedThreadPool

通过Executors.newCachedThreadPool()创建。

new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>())

CachedThreadPool是线程数量不固定的线程池,由于指定最大线程数为Integer.MAX_VALUE,基本相当于无限制。SynchronousQueue是一种特殊的队列,可以简单理解为无法存储元素的队列,因此每来一个任务就会创建一个新线程。

ScheduledThreadPool

通过Executors.newScheduledThreadPool()创建。

public static ScheduledExecutorService newScheduledThreadPool(
            int corePoolSize, ThreadFactory threadFactory) {
        return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
    }
public ScheduledThreadPoolExecutor(int corePoolSize,
                                       ThreadFactory threadFactory) {
        super(corePoolSize, Integer.MAX_VALUE,
              DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
              new DelayedWorkQueue(), threadFactory);
    }

ScheduledThreadPool是一种核心线程固定,非核心线程不限制的线程池,主用用来执行定时任务或周期任务。
ScheduledExecutorService的schedule方法。

public ScheduledFuture<?> schedule(Runnable command,
                                       long delay, TimeUnit unit);

参考《Android 开发艺术探索》

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!