• 多线程之ThreadPoolExecutor


    关系类图为:

    在这里插入图片描述

    1 线程池状态

    ThreadPoolExecutor 使用 int 的高 3 位来表示线程池状态,低 29 位表示线程数量

    状态名高3位接收新任务处理阻塞队列任务说明
    RUNNING111YY
    SHUTDOWN000NY不会接收新任务,但会处理阻塞队列剩余 任务
    STOP001NN会中断正在执行的任务,并抛弃阻塞队列 任务
    TIDYING010任务全执行完毕,活动线程为 0 即将进入 终结
    TERMINATED011终结状态

    从数字上比较,TERMINATED > TIDYING > STOP > SHUTDOWN > RUNNING

    信息存储在一个原子变量 ctl 中,目的是将线程池状态与线程个数合二为一,这样就可以用一次 cas 原子操作 进行赋值

    // c 为旧值, ctlOf 返回结果为新值
    ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))));
    // rs 为高 3 位代表线程池状态, wc 为低 29 位代表线程个数,ctl 是合并它们
    private static int ctlOf(int rs, int wc) { return rs | wc; }
    
    • 1
    • 2
    • 3
    • 4

    2 构造方法

    public ThreadPoolExecutor(int corePoolSize,
     int maximumPoolSize,
     long keepAliveTime,
     TimeUnit unit,
     BlockingQueue<Runnable> workQueue,
     ThreadFactory threadFactory,
    RejectedExecutionHandler handler)
    /*
    参数说明:
    corePoolSize 核心线程数目 
    maximumPoolSize 最大线程数目
    keepAliveTime 生存时间 
    unit 时间单位 
    workQueue 阻塞队列
    threadFactory 线程工厂 - 可以为线程创建时起个好名字
    handler 拒绝策略
    */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    工作方式:

    • 线程池中刚开始没有线程,当一个任务提交给线程池后,线程池会创建一个新线程来执行任务

    • 当线程数达到 corePoolSize 并没有线程空闲,这时再加入任务,新加的任务会被加入workQueue 队列排 队,直到有空闲的线程

    • 如果队列选择了有界队列,那么任务超过了队列大小时,会创建 maximumPoolSize - corePoolSize 数目的线 程来救急

    • 如果线程到达 maximumPoolSize 仍然有新任务这时会执行拒绝策略。拒绝策略 jdk 提供了 4 种实现,其它 框架也提供了不同的实现

      • jdk
        • AbortPolicy 让调用者抛出 RejectedExecutionException 异常,默认策略
        • CallerRunsPolicy 让调用者运行任务
        • DiscardPolicy 放弃本次任务
        • DiscardOldestPolicy 放弃队列中最早的任务,本任务取而代之
      • Dubbo 的实现,在抛出 RejectedExecutionException 异常之前会记录日志,并 dump 线程栈信息,方 便定位问题
      • Netty 的实现,是创建一个新线程来执行任务
      • ActiveMQ 的实现,带超时等待(60s)尝试放入队列
      • PinPoint 的实现,它使用了一个拒绝策略链,会逐一尝试策略链中每种拒绝策略 (类似责任链那种)
    • 当高峰过去后,超过corePoolSize 的救急线程如果一段时间没有任务做,需要结束节省资源,这个时间由 keepAliveTime 和 unit 来控制。

    拒绝策略类图

    在这里插入图片描述

  • 相关阅读:
    没有想好标题
    二叉树-31-37对称二叉树
    图像处理与计算机视觉--第四章-图像滤波与增强-第二部分
    哈佛国际评论比赛秋季赛抓紧时间准备起来
    图解 SQL 执行顺序,通俗易懂!
    How to config secured and stable Jenkins connection
    Java基于springboot+vue的个人博客网站 前后端分离
    Codeforces 353D 思维
    华为云API图像识别Image的趣味性—AI识别迈克尔·杰克逊
    约会怎么走到目的地最近呢?一文讲清所有最短路算法问题
  • 原文地址:https://blog.csdn.net/ABestRookie/article/details/126274823