19. 线程池

作者: from0 | 来源:发表于2018-05-27 23:04 被阅读30次

Android 中的线程池就是 java 中的线程池,即 ThreadPoolExecutor 类。

Java 通过 Executors 提供四种线程池:

  1. newCachedThreadPool

    创建一个可缓存的线程池

  2. newFixedThreadPool

    创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。

  3. newScheduledThreadPool

    创建一个定长线程池,支持定时及周期性任务执行。

  4. newSingleThreadExecutor

    创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

Executors 是一个线程池的工具类,上面四个方法最终都是调用的 ThreadPoolExecutor。理解 ThreadPoolExecutor 就可以完全理解线程池。

线程池解决了 2 个问题:

  1. 当执行大量异步任务时,通过减少每个任务的调用开销来提高性能。
  2. 提供了限制管理线程资源的方法。

ThreadPoolExecutor

public class ThreadPoolExecutor extends AbstractExecutorService 

构造

    /**
     *
     * @param corePoolSize  保持在线程池中的线程数,即使线程处于空闲状态,除非设置了 allowCoreThreadTimeOut
     * @param maximumPoolSize 线程最大数量
     * @param keepAliveTime 线程数大于 corePoolSize 时,线程池中的空闲线程等待新任务执行的最大时间,超过这个时间,空闲线程就会被终止。
     * @param unit keepAliveTime 的时间单位
     * @param workQueue 任务队列
     * @param threadFactory 线程工厂
     * @param handler 线程被阻塞时的处理者,因为到达了线程的最大数量或者任务队列满了。
     */
    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;
    }

执行流程

执行流程可以用这张图来概括:


image

通过 execute()方法执行线程池,内部会自动根据我们构造参数的信息分配处理 Runnable。

    public void execute(Runnable command) {
        // Runnable 不可以为空
        if (command == null)
            throw new NullPointerException();
        
        // ctl 是一个 AtomicInteger,用来记录正在运行的线程数量
        int c = ctl.get();
        // 当前核心的线程数量<corePoolSize,就新开一个线程将任务放进去
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        
        // 核心线程正在运行,且任务队列没满
        if (isRunning(c) && workQueue.offer(command)) {
            // 重新检查核心线程
            int recheck = ctl.get();
            // 核心线程没有运行就移除任务,实施拒绝策略
            if (! isRunning(recheck) && remove(command))
                reject(command);
            // 核心线程数量为0,开一个线程
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        // 任务队列
        else if (!addWorker(command, false))
            reject(command);
    }

参考

深入理解Java之线程池

Android 开发艺术探索 11.3

相关文章

  • 19. 线程池

    Android 中的线程池就是 java 中的线程池,即 ThreadPoolExecutor 类。 Java 通...

  • java线程池

    线程VS线程池 普通线程使用 创建线程池 执行任务 执行完毕,释放线程对象 线程池 创建线程池 拿线程池线程去执行...

  • java----线程池

    什么是线程池 为什么要使用线程池 线程池的处理逻辑 如何使用线程池 如何合理配置线程池的大小 结语 什么是线程池 ...

  • Java线程池的使用

    线程类型: 固定线程 cached线程 定时线程 固定线程池使用 cache线程池使用 定时调度线程池使用

  • Spring Boot之ThreadPoolTaskExecut

    初始化线程池 corePoolSize 线程池维护线程的最少数量keepAliveSeconds 线程池维护线程...

  • 线程池

    1.线程池简介 1.1 线程池的概念 线程池就是首先创建一些线程,它们的集合称为线程池。使用线程池可以很好地提高性...

  • 多线程juc线程池

    java_basic juc线程池 创建线程池 handler是线程池拒绝策略 排队策略 线程池状态 RUNNIN...

  • ThreadPoolExecutor线程池原理以及源码分析

    线程池流程: 线程池核心类:ThreadPoolExecutor:普通的线程池ScheduledThreadPoo...

  • 线程池

    线程池 [TOC] 线程池概述 什么是线程池 为什么使用线程池 线程池的优势第一:降低资源消耗。通过重复利用已创建...

  • java 线程池使用和详解

    线程池的使用 构造方法 corePoolSize:线程池维护线程的最少数量 maximumPoolSize:线程池...

网友评论

    本文标题:19. 线程池

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