• 22、7大参数自定义线程池(核心线程数,最大核心线程数。。。拒绝策略(4种))


    7大参数自定义线程池(核心线程数,最大核心线程数。。。拒绝策略(4种))

    第一步:我们首先看单例线程池的源码

     

    第二步:多个固定线程的线程池源码

     

    第三步:可变的线程数的线程池源码

     

    开启线程池的本质(调用ThreadPoolExecutor())

    进去调用的this,再往下走

     

    !!!走this方法里(可以看到有7个参数)

    *corePoolSize:核心线程数

    *maximumPoolSize:最大核心线程池大小(是包括前面的核心线程数的。前面为2,设置为5,那么旁边就是剩3个封存着的)

    *keepAliveTime:超时无人调用就会释放

    *TimeUnit:超时单位

    *BlockingQueue:阻塞队列

    *ThreadFactory:线程工厂,创建线程的(一般不用动)

    *RejectExecutionHandler:拒绝策略(有四种的)

     

     

     

    分析源码:

     

    因为我们这个若是用的Executors去创建线程池的话,那么可以看到这个CachedThreadPool可能会创建大量的线程(最多21亿)从而导致OOM

     

    !!!7大参数模型:(这里也说下线程池的运行逻辑)

    首先我们线程池里面有几个东西这样说吧,核心线程数,最大线程数(阻塞队列吗,满了才开启的),阻塞队列,拒绝策略。

    1. 我们我们有任务进来,先看下核心线程是否有空闲,若是有空闲就用空闲线程来执行2、若是核心线程数都被占用,那么就会将任务放到阻塞队列
    2. 若是阻塞队列都放满了,那么我们就使用最大线程数的线程来执行

    4、若是最大线程数也满了,那就4种拒绝策略拒绝咯

     

    代码操作:

     

    Executors默认使用AborPolicy(不处理,抛出异常)

     

    第一步:5个人进去(2个核心数处理,3个再阻塞队列里面,最大5个个核心线程数(3个在等待阻塞队列满了唤醒))

     

    两个核心线程在使用

     

    第二步:进去6个人(就会使用2个核心线程和,一个最大线程数里的了,(3个再阻塞队列里))

     

     

    同理7个线程,就会触发线程池中4个线程数处理。

    9个就会触发拒接策略了(这里是不处理,抛出异常(5+3)线程池最多容纳8个线程)

     

    里面最多5个核心线程数跑,然后最多容纳8个,有一个就拒绝策略,这里是不处理抛出异常(.AbortPolicy())

     

    !!!第二种拒绝策略:(CallerRunsPolicy(哪来的去哪里))这里我们是main线程创建的,所以就是main线程去处理

     

    看到没有是main去处理的,滚回去让创建你的处理去(拒绝策略)5个最大核心线程+main线程

     

    !!第三个拒绝策略(DisCarPolict(队列满了,丢掉任务(不处理)不会抛出异常))

     

    这里看到,没有处理,也不会抛出异常

     

    拒绝策略4、(DiscardOldestPolicy(队列满了,尝试和最早的线程竞争,竞争失败就不执行咯(不是直接不执行),也是不会抛出异常的(是我们DIs上面的升级版嘛)))

     

    没有抛出异常,尝试和最早的线程竞争

     

     总结:

     

    1. package org.example.threadpoolexecutor;
    2. import java.util.concurrent.*;
    3. public class TestThreadPoolSeven {
    4.     public static void main(String[] args) {
    5.         System.out.println(Runtime.getRuntime().availableProcessors());
    6.         ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
    7.                 2,//核心线程是
    8.                 Runtime.getRuntime().availableProcessors(),//最大线程数
    9.                 0L,//超时多久没人调用会释放
    10.                 TimeUnit.MINUTES,//超时单位
    11.                 new LinkedBlockingDeque<>(3),//阻塞队列(大小为3)
    12.                 Executors.defaultThreadFactory(),//线程工厂,一般不会动
    13. //                new ThreadPoolExecutor.AbortPolicy());//超过容量,不处理抛出异常
    14. //                new ThreadPoolExecutor.CallerRunsPolicy());//超出容量,线程池不处理,返回给创建他的处理
    15. //                new ThreadPoolExecutor.DiscardPolicy());//不处理,直接丢弃。不抛异常
    16.                 new ThreadPoolExecutor.DiscardOldestPolicy());//不直接抛弃,而是和最早的线程竞争线程
    17.         try {
    18.             for (int i = 1; i <=9; i++) {
    19.                 threadPool.execute(()->{
    20.                     System.out.println(Thread.currentThread().getName()+"=>ok");
    21.                 });
    22.             }
    23.         } catch (Exception e) {
    24.             throw new RuntimeException(e);
    25.         } finally {
    26.             threadPool.shutdown();
    27.         }

  • 相关阅读:
    Mybatis-尚硅谷-学习笔记
    CaiT:Facebook提出高性能深度ViT结构 | ICCV 2021
    上下架和橱窗推荐如何设置,优化过程需要注意的地方
    八大排序之插入排序
    力扣题(5)—— 最长回文子串
    KT6368A蓝牙芯片的天线注意事项_倒F型-蛇形_陶瓷天线的区别
    多维时序 | MATLAB实现SSA-CNN-BiGRU-Attention多变量时间序列预测(SE注意力机制)
    C++智能指针之weak_ptr
    [nlp] 自然语言理解基准 ATIS Snips
    【MySQL】sql语句之库操作
  • 原文地址:https://blog.csdn.net/logtcm4/article/details/127886874