Android 中的 线程池

java 复制代码
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

1、corePoolSize 用于指定线程池的核心线程数大小;

2、maximumPoolSize 用于指定最大线程池大小。

3、keepAliveTime,unit 一起用于指定线程池中空闲线程的最大存活时间。

4、workQueue 任务队列,相当于生产者 - 消费者模式中的传输管道,用于存放待处理的任务。

5、threadFactory 用于指定创建线程的线程工厂。

6、handler 用于指定当任务队列已满且线程数量达到 maximumPoolSize 时任务的处理策略。

一、newFixedThreadPool

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

核心线程数和最大线程数都是 nThreads , 所以线程池在任何时候最多也只会有 nThreads 个线程在同时运行,且在停止线程池前所有线程都不会被回收。LinkedBlockingQueue 的默认容量是 Integer.MAX_VALUE , 近乎无限,在线程繁忙的情况下有可能导致等待处理的任务持续堆积,使得系统频繁GC ,最终导致 OOM。

此类线程池适合用于希望所有任务都能够被执行的情况

二、 newSingleThreadExecutor

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

newSingleThreadExecutor ,核心线程数和最大线程数都是1,所以线程池在任何时候也只能会由一个线程在同时运行,且在停止线程前所有线程都不会被回收。由于使用了 LinkedBlockingQueue ,所以在极端情况下也是有发生 OOM 的可能。

此类线程适合用于执行需要串行处理的任务,或者是任务提交间隔比任务的执行时间长的情况。

三、newCachedThreadPool

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

newCachedThreadPool , 核心线程数是0,最大线程数 MAX_VALUE,所以允许同时运行的线程数量近乎无限。再加上 SynchronousQueue 是一个储存元素的阻塞队列,每当有新任务到来时,如果当前没有空闲线程的话就会马上启动一个新的线程来执行任务,这使得任务重视能够很快被执行,提升了响应速度,但同时也存在由于要执行的任务过多导致一直创建线程的可能,这在任务耗时过长且任务量过多的情况下也可能导致 OOM。

此类线程池适合用于对任务的处理速度要求比较高的情况。

四、ScheduledThreadPoolExecutor

java 复制代码
    public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }
java 复制代码
    public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE,
              DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
              new DelayedWorkQueue());
    }

newScheduledThreadPool方法创建的线程对应是 ScheduledThreadPoolExecutor,ScheduledThreadPoolExecutor的核心线程数由入参 corePoolSize 决定,最大线程数是 MAX_VALUE,keepAliveTime 是0秒,所以该线程池可能同时运行近乎无限的线程,但一旦当前没有待执行的任务的话,线程就会马上被回收。

此类线程适合用于需要定时多次执行特定任务的情况。

参考:

https://github.com/leavesCZY/AndroidGuide/blob/master/Java%20%E5%A4%9A%E7%BA%BF%E7%A8%8B%E5%BC%80%E5%8F%91%EF%BC%885%EF%BC%89%E8%B6%85%E8%AF%A6%E7%BB%86%E7%9A%84%20ThreadPoolExecutor%20%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90.md

相关推荐
艾莉丝努力练剑4 分钟前
【LeetCode&数据结构】单链表的应用——反转链表问题、链表的中间节点问题详解
c语言·开发语言·数据结构·学习·算法·leetcode·链表
武子康1 小时前
Java-72 深入浅出 RPC Dubbo 上手 生产者模块详解
java·spring boot·分布式·后端·rpc·dubbo·nio
_殊途2 小时前
《Java HashMap底层原理全解析(源码+性能+面试)》
java·数据结构·算法
椰椰椰耶3 小时前
【Spring】拦截器详解
java·后端·spring
没有bug.的程序员4 小时前
JAVA面试宝典 - 《MyBatis 进阶:插件开发与二级缓存》
java·面试·mybatis
没有羊的王K5 小时前
SSM框架学习——day1
java·学习
珊瑚里的鱼5 小时前
LeetCode 692题解 | 前K个高频单词
开发语言·c++·算法·leetcode·职场和发展·学习方法
又菜又爱coding5 小时前
安装Keycloak并启动服务(macOS)
java·keycloak
不知道叫什么呀5 小时前
【C】vector和array的区别
java·c语言·开发语言·aigc
wan_da_ren6 小时前
JVM监控及诊断工具-GUI篇
java·开发语言·jvm·后端