Android中的线程池

线程池的好处

(1)重用线程池中的线程,避免因为线程的创建和销毁所带来的性能的开销。
(2)能有效控制线程池的最大并发数,避免线程间因抢占系统资源而导致线程阻塞。
(3)能够对线程进行管理,并提供定时执行及指定间隔循环执行等功能

线程池的配置

ThreadPoolExecutor是线程池的正真实现


  public ThreadPoolExecutor(int corePoolSize,
                            int maximumPoolSize,
                            long keepAliveTime,
                            TimeUnit unit,
                            BlockingQueue workQueue,
                            ThreadFactory threadFactory) 

corePoolSize

线程池的核心线程数,默认情况下,核心线程在线程池中一直存活。如果将ThreadPoolExecutor的allowCoreThreadTimeOut属性设置为true,那么闲置的核心线程会有超时策略,这个时间由keepAliveTime所指定,当时间超过keepAliveTime所指定的时间后,核心线程就会被终止。

maximumPoolSize

线程池所能容纳的最大线程数,当活动线程数达到这个值后,后续任务将会被阻塞。

keepAliveTime

非核心线程闲置时的超时时长,超过这个时间,非核心线程就会被回收。如果将ThreadPoolExecutor的allowCoreThreadTimeOut属性设置为true,keepAliveTime同样会作用于核心线程

unit

keepAliveTime参数的时间单位,是一个枚举类型,常用的有TimeUnit.MILLISECONDS(毫秒)、TimeUnit.SECONDS(秒)、TimeUnit.MINUTES(分钟)等

BlockingQueue workQueue

线程池中的任务队列,通过线程池的execute方法提交的Runnable对象存储在这个参数中。

threadFactory

线程工厂,为线程池提供创建线程的功能。ThreadFactory是一个接口,只有一个方法 Thread new Thread(Runnable runnable)

ThreadPoolExecutor执行任务时的规则:

(1)如果线程池中的线程数量未达到核心线程的数量,那么会直接启动一个核心线程来执行任务。

(2)如果线程池中的线程数量已达到或者超过核心线程的数量,那么任务会被插入到任务队列中排队等待执行。

(3)如果无法将任务插入任务队列中(任务队列已满),这时候如果线程池中的线程数量未达到线程池规定的最大值,那么会立刻启动一个非核心线程来执行任务。

ThreadPoolExecutor在AsyncTask中的配置

用于AsyncTask封装了线程池,我们从AsyncTask源码中可以看出AsyncTask对ThreadPoolExecutor的配置

public abstract class AsyncTask
{
    private static final String LOG_TAG = "AsyncTask";
    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    // We want at least 2 threads and at most 4 threads in the core pool,
    // preferring to have 1 less than the CPU count to avoid saturating
    // the CPU with background work
    private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
    private static final int KEEP_ALIVE_SECONDS = 30;

    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());
        }
    };

    private static final BlockingQueue sPoolWorkQueue =
            new LinkedBlockingQueue(128);

    /**
     * An {@link Executor} that can be used to execute tasks in parallel.
     */
    public static final Executor THREAD_POOL_EXECUTOR;

    static {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
                sPoolWorkQueue, sThreadFactory);
        threadPoolExecutor.allowCoreThreadTimeOut(true);
        THREAD_POOL_EXECUTOR = threadPoolExecutor;
}

线程池的分类

Android中四类具有不同功能特征的线程池,它们都直接或者间接地通过配置ThreadPoolExecutor来实现自己的功能特性

FixedThreadPool

通过Executors的newFixedThreadPool来创建

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

是一种线程数量固定的线程池,当线程处于空闲状态时,不会被回收,当所有线程都处于活动状态时,新任务将处于等待状态,直到有线程空闲出来。FixedThreadPool中只有核心线程并且核心线程没有超时限制

newCachedThreadPool

通过Executors的newCachedThreadPool来创建

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

可以看出它没有核心线程,线程数量不定Integer.MAX_VALUE,超时时长为60秒,比较适合执行大量的耗时较少的任务。

ScheduledThreadPool

通过Executors的newScheduledThreadPool来创建

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

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

核心线程数量是固定的,非核心线程的数量没有限制,并且非核心线程闲置时会被立即回收。主要用于执行定时任务和具有固定周期的重复任务。

SingleThreadExecutor

通过Executors的newSingleThreadExecutor来创建

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

只有一个核心线程,它确保所有的任务都在同一个线程中按顺序执行。不需要处理线程同步的问题。

你可能感兴趣的:(Android中的线程池)