美文网首页跨进程通信
Android中的线程池

Android中的线程池

作者: 蓝枫zeke | 来源:发表于2016-12-16 09:46 被阅读39次

    线程池的好处

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

    线程池的配置

    ThreadPoolExecutor是线程池的正真实现

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

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

    maximumPoolSize

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

    keepAliveTime

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

    unit

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

    BlockingQueue<Runnable> workQueue

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

    threadFactory

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

    ThreadPoolExecutor执行任务时的规则:

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

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

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

    ThreadPoolExecutor在AsyncTask中的配置

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

    public abstract class AsyncTask<Params, Progress, Result>
    {
        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<Runnable> sPoolWorkQueue =
                new LinkedBlockingQueue<Runnable>(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<Runnable>());
        }
    

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

    newCachedThreadPool

    通过Executors的newCachedThreadPool来创建

      public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
            return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                          60L, TimeUnit.SECONDS,
                                          new SynchronousQueue<Runnable>(),
                                          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<Runnable>()));
        }
    

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

    相关文章

      网友评论

        本文标题:Android中的线程池

        本文链接:https://www.haomeiwen.com/subject/rwcnmttx.html