• ThreadPool线程池


    一、ThreadPool线程池

    在这里插入图片描述

    1.为什么要用线程池

    例子:
    10年前单核CPU电脑,假的多线程,像马戏团小丑玩多个球,CPU需要来回切换。
    现在是多核电脑,多个线程各自跑在独立的CPU上,不用切换效率高。
    线程池的优势:
    线程池做的工作只要是控制运行的线程数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,如果线程数量超过了最大数量,超出数量的线程排队等候,等其他线程执行完毕,再从队列中取出任务来执行。
    它的主要特点为:线程复用;控制最大并发数;管理线程。
    第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的销耗。
    第二:提高响应速度。当任务到达时,任务可以不需要等待线程创建就能立即执行。
    第三:提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会销耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。

    2.线程池的架构

    在这里插入图片描述

    3.线程池的种类

    第一种
    Executors.newFixedThreadPool(10); 初始化线程池的大小.
    在这里插入图片描述
    第二种
    Executors.newSingleThreadExecutor(); 一池,一线程!
    在这里插入图片描述
    第三种
    Executors.newCachedThreadPool(); 执行异步短期任务,可扩容.
    在这里插入图片描述

    三种创建线程池的方式:底层都是new ThreadPoolExecutor();
    用线程池:使用哪一种?都不用!
    自定义线程池:
    new ThreadPoolExecutor(0, Integer.MAX_VALUE,
    60L, TimeUnit.SECONDS,
    new SynchronousQueue());

    4.线程池的7个参数

    1、corePoolSize:线程池中的常驻核心线程数
    2、maximumPoolSize:线程池中能够容纳同时执行的最大线程数,此值必须大于等于1
    3、keepAliveTime:多余的空闲线程的存活时间,当前池中线程数量超过corePoolSize时,当空闲时间达到keepAliveTime时,多余线程会被销毁直到只剩下corePoolSize个线程为止
    4、unit:keepAliveTime的单位
    5、workQueue:任务队列,被提交但尚未被执行的任务
    6、threadFactory:表示生成线程池中工作线程的线程工厂,用于创建线程,一般默认的即可
    7、handler:拒绝策略,表示当队列满了,并且工作线程大于等于线程池的最大线程数(maximumPoolSize)时如何来拒绝请求执行的runnable的策略

    5.线程池底层工作原理

    在这里插入图片描述
    在这里插入图片描述

    6.线程池的拒绝策略

    以下内置拒绝策略均实现了RejectedExecutionHandle接口
    1.AbortPolicy(默认):直接抛出RejectedExecutionException异常阻止系统正常运行
    2.CallerRunsPolicy:“调用者运行”一种调节机制,该策略既不会抛弃任务,也不会抛出异常,而是将某些任务回退到调用者,从而降低新任务的流量。
    3.DiscardOldestPolicy:抛弃队列中等待最久的任务,然后把当前任务加人队列中尝试再次提交当前任务。
    4.DiscardPolicy:该策略默默地丢弃无法处理的任务,不予任何处理也不抛出异常。如果允许任务丢失,这是最好的一种策略。

    7.面试题:在工作中三种创建线程池的方法哪个用的多?

    超级大坑
    答案:是一个都不用,我们工作中只能使用自定义的
    Executors中JDK已经给你提供了,为什么不用?
    在这里插入图片描述
    解释FixedThreadPool 和 SingleThreadPool:
    相当于核心线程数就等于最大线程池数,可能会导致堆积大量的请求
    在这里插入图片描述

    在这里插入图片描述
    解释CachedThreadPool
    会创建大量的线程
    在这里插入图片描述

    8.在工作中如何使用线程池,是否自定义过线程池

    ```csharp
    public class MyThreadPoolDemo {
        public static void main(String[] args) {
            //自定义线程池
            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                    2,  //核心线程池
                    5,   //最大线程池
                    3L,  //空闲线程的存活时间
                    TimeUnit.SECONDS,  //空闲线程存活时间单位
                    new ArrayBlockingQueue<>(3), //阻塞队列个数
                    Executors.defaultThreadFactory(), //使用默认的工厂值
               //     new ThreadPoolExecutor.AbortPolicy() //默认值:直接发生异常,组织运行
               //     new ThreadPoolExecutor.DiscardOldestPolicy() //抛弃等待最久的任务,尝试加入新的任务
               //     new ThreadPoolExecutor.CallerRunsPolicy()  //调用者执行任务
                    new ThreadPoolExecutor.DiscardPolicy()
    
            );
    
            //银行处理业务:10个顾客来办理业务!
            //暂时处理6个顾客
            try {
                for (int i = 1; i <= 10  ; i++) {
                   threadPoolExecutor.execute(()->{
                       System.out.println(Thread.currentThread().getName()+"\t 处理业务");
                   });
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                threadPoolExecutor.shutdown();
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    
    
    • 1
  • 相关阅读:
    Kubernetes学习笔记-StatefulSet:部署有状态的多副本应用(1)20220624
    zero-shot, one-shot和few-shot
    C++的可见性
    深入理解数据库事务:确保数据完整性与一致性
    UE4 设计模式:单例模式(Singleton Pattern)
    Unity 动画知识点
    pid 电机控制算法
    Part4_场景_第60章 阿利亚加&第61章 基于MATSim的新住户效用函数检验:以保定市为例
    什么是RabbitMQ
    Flink集群配置
  • 原文地址:https://blog.csdn.net/qq_46548855/article/details/125963423