安卓开发中线程池ThreadPoolExecutor的总结

线程池的优点
1、复用线程池中的线程,避免创建销毁的性能开销
2、有效控制线程池的最大并发数
3、能有效的管理线程
4、可定时执行且指定间隔循环执行

ThreadPoolExecutor:线程池的真正实现类。谷歌推荐使用 Executors 的工厂方法来创建线程池(下面线程池的分类有说到)
ThreadPoolExecutor的构造方法:参数的不同直接影响线程池的功能特性。

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

相关参数的介绍:
corePoolSize:线程池的核心线程数(没有设置allowCoreThreadTimeOut为true时不会被回收)
maximumPoolSize:最大线程数,当到达最大线程数后,后续新任务将会被阻塞
keepAliveTime:非核心线程闲置的超时时长,超过该时长则被回收。(当allowCoreThreadTimeOut属性设置为true时,keepAliveTime超时后也同样会对核心线程进行回收)
unit:指定keepAliveTime的时间单位,是个枚举常用有 TimeUnit.MILLISECONDS(毫秒)、TimeUnit.SECONDS(秒)、TimeUnit.MINUTES(分钟)
workQueue:线程池中的任务队列,通过线程池中的execute方法提交的Runnable对象会存储在这个参数中。
threadFactory:线程工厂,为线程池提供创建新线程的功能。(接口,只有一个方法:Thread newThread(Runnable r))
RejectedExecutionHandler:当线程无法执行新任务时,可能队列已满或者是无法成功执行任务。会抛出rejectedExecution异常(DiscardOldestPolicy、DiscardPolicy、AbortPolicy、CallerRunsPolicy)

执行规则:(currentSize:代表当前线程数量)
1、当currentSize < corePoolSize时,直接启动核心线程来执行任务。
2、当currentSize >= corePoolSize时,新任务插入任务队列排队等待执行。
3、当任务队列已满,currentSize < maximumPoolSize,则立刻启动非核心线程来执行任务。
4、当任务队列已满,currentSize > maximumPoolSize,则拒绝执行任务,ThreadPoolExecutor会调用RejectedExecutionHandler的rejectedExecution方法来通知调用者。

线程池的分类:
FixedThreadPool:数量固定并都是核心线程的线程池,线程空闲时不会被回收,除非线程池关闭、没有超时机制,没有任务大小限制,通过Executors.newFixedThreadPool()创建
相关代码:

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

CachedThreadPool:数量不定并都是非核心线程的线程池,最大线程数是Integer.MAX_VALUE(因为很大,所以算是任意大),有空闲线程就用空闲线程来处理新任务,否者直接创建新线程处理。超时是60秒,超过60秒就被回收。通过Executors.newCachedThreadPool()创建
相关代码:

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

ScheduledThreadPool:固定的核心线程数,没有限制的非核心线程(闲置时立即回收),这类线程池主要用于执行定时任务和具有固定周期的重复任务 通过Executors.newScheduledThreadPool()来创建
相关代码:

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

SingleThreadExecutor:只有一个核心线程,确保所有的任务都在同一个线程中按顺序执行 ,SingleThreadExecutor 的意义在于统一所有的外界任务到一个线程中,这使得这些任务之间不需要处理线程同步的问题。通过 Executors.newSingleThreadExecutor()来创建
相关代码:

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

总结
1. FixedThreadPool 只有核心线程,并且数量是固定的,也不会被回收,能更快地响应外界请求。
2. CachedThreadPool 只有非核心线程,最大线程数非常大,所有线程都活动时,会为新任务创建新线程,否则利用空闲线程处理任务,任何任务都会被立即执行。
4. ScheduledThreadPool 核心线程数固定,非核心线程数没有限制,主要用于执行定时任务以及有固定周期的重复任务。
4. SingleThreadPool 只有一个核心线程,确保所有任务都在同一线程中按顺序完成。因此不需要处理线程同步的问题。

猜你喜欢

转载自blog.csdn.net/qq_33373648/article/details/80375083
今日推荐