线程池_02_Executor框架

简介:

线程池_02_Executor框架
  • 一、Executor 的两级调度
    • 背景知识
      • 在HotSpot Vm 的线程模型中,Java 线程被一对一映射为本地操作系统线程。Java 线程启动时会创建一个本地操作系统线程;当该Java线程终止时,这个操作系统线程也会被回收。
    • Executor
      • 在上层,Java多线程程序通常把应用分解为若干个任务,然后使用用户级的调度器(Executor框架)将这些任务映射为固定数量的线程;换句话说就是应用程序通过Executor框架控制上层的调度。
      • 在底层,操作系统内核将这些线程映射到硬件处理器上。换句话说,下层的调度由操作系统内核控制,下层的调度不受应用程序的控制。
  • 二、Executor 的组成
    • 1、任务;
      • 包括被执行任务需要实现的接口:Runbable或Callable 接口
    • 2、任务的执行;
      • 包括任务执行机制的核心接口Executor,以及继承自Executor 的ExecutorService接口。Executor 框架有两个关键类实现了ExecutorService 接口
    • 3、异步计算的结果;
      • 包括接口Future 和 实现Future接口的FutureTask类。
  • 三、Executor 使用
    • 1、主线程首先创建Runnable或Callable的任务对象A;
    • 2、然后把对象A直接交给ExecutorService通过Execute或Submit方法执行;
    • 3、如果使用的是submit方法,会返回一个实现Future接口的对象,主线程可以执行FutureTask.get()方法来等待任务执行完成。也可以执行FutureTask.cancle()来取消任务。
  • 四、Executor 主要的类与接口的简介
    • 1、Executor
      • 接口,是Executor框架的基础,它将任务的提交与任务的执行分离开来。
    • 2、ThreadPoolExecutor
      • 线程池的核心实现类,用来执行被提交的任务
    • 3、ScheduledThreadPoolExecutor(定时任务类,这里不讨论)
      • 实现类,可以在给定的延迟后运行命令,或者定期执行命令。
    • 4、Future接口和实现Future接口的FutureTask类,代表异步结算的结果
    • 5、Runnable 和Callable接口的实现类
  • 五、Executor 主要的类与接口的详解
    • ThreadPoolExecutor
      • 四个核心参数:
        • 1、corePool 核心线程池的大小;
        • 2、maximumPool 最大线程池的大小;
        • 3、BlockingQueue 用来暂时保存任务的工作队列;
        • 4、RejectedExecutionHandler 当ThreadPoolExecutor 可以关闭或ThreadExecutor 已经饱和时(达到了最大线程池大小并且工作队列已满),execute()方法将要调用的Handler。
      • ThreadPoolExecutor通常使用工厂类Executors来创建,Executors可以创建3种类型的ThreadPoolExecutor: FixedThreadPool、SingleThreadExecutor、CachedThreadPool;
        • 1、FixedThreadPool ,创建固定线程数的API。
          ac344291-4210-4332-93aa-4b6b753ce0e2-5210562.jpg
          • 创建的方法:
            76f90e81-fae7-483d-9a7d-42cba1d3bc40-5210562.jpg
            • FixedThreadPool 的核心线程和最大线程数是一样的;线程的空闲存活时间为0,则多余的空闲线程会被立即终止。
          • 执行execute(),流程如下:
            • 1、如果当前运行的线程数少于corePoolSize,则创建新线程来执行任务;
            • 2、如果当前运行的线程数等于corePoolSize,将任务加入LinkedBlockingQueue;
            • 3、线程执行完1中的任务后,会在循环中反复从LinkedBlockingQueue获取任务来执行。
          • 使用无界队列LinkedBlockingQueue,影响:
            • 1、如果当前运行的线程数等于corePoolSize,新任务将在无界队列中等待,因此线程池中的线程数不会超过corePoolSize;
            • 2、maximumPoolSize 与 keepAliveTime 会是无效的;
            • 3、运行中的FixedThreadPool 不会拒绝任务(因为工作队列可以无限增大);
        • 2、SingleThreadExecutor,使用单个工作线程的Executor。
          • 创建的方法:
            a097a384-3748-49ac-8e75-cab609957ca5-5210562.jpg
            • 于corePoolSize与maximumPoolSize 设为1,其它参数与FixedThreadPool一样。
          • 执行execute(),流程如下:
            • 1、如果线程池中无运行的线程,则创建一个新线程来执行任务;
            • 2、当前线程池中有一个运行的线程,将任务加入LinkedBlockingQueue;
            • 3、线程执行完1中的任务后,会在循环中反复从LinkedBlockingQueue获取任务来执行。
          • 使用无界队列LinkedBlockingQueue,与FixedThreadPool一样的结果。
        • 3、CachedThreadPool,根据需要创建新线程的线程池。
          • 创建的方法:
            6a95a009-5173-4dad-bdf2-30b8600cf0fc-5210562.jpg
            • corePoolSize 为0,maximumPoolSize被设置为Integer.MAX_VALUE,即是maximumPoolSize无界的。keepAliveTime 设为60秒,空闲存活60秒后被终止。
          • CachedThreadPool 使用没有容量的SynchronousQueue作为线程池的工作队列,但是maximumPoolSize是无界的。这意味着,如果主线程提交任务的速度高于maximumPool中线程处理任务的速度时,CachedThreadPool会不断创建新线程。极端情况下,CachedThreadPool会因为创建过多线程而耗尽CPU和内存资源。
        • 总结:
          • FixedThreadPool 与 SingleThreadExecutor 允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而引起OOM异常
          • CachedThreadPool => 允许创建的线程数为Integer.MAX_VALUE,可能会创建大量的线程,从而引起OOM异常
    • FutureTask
      • 使用:
        • 1、由调用线程直接执行FutureTask.run(); ---- 实现了Runnable接口
        • 2、通过ExecutorService.submit()方法返回一个FutureTask; ---- 实现了Future 接口
      • 实现原理
        • 基于AbstractQueuedSynchronizer(简称AQS)。AQS是一个同步框架,它提供通用机制来原子性管理同步状态、阻塞和唤醒线程,以及维护被阻塞线程的队列。
        • 基于AQS实现的同步器包含两种类型:
          • 1、至少一个acquire操作。这个操作阻塞调用线程,除非/直到AQS的状态允许这个线程继续执行。
            • 在FutureTask 类中get()和get(long timeout, TimeUnit unit)两个方法为acquire操作;
          • 2、至少一个release操作。这个操作改变AQS的状态,改变后的状态可允许一个或多个阻塞线程被解除阻塞。
            • 在FutureTask 类中run()和cancel()两个方法为acquire操作;

相关文章
|
6月前
|
人工智能 JSON 前端开发
【Spring boot实战】Springboot+对话ai模型整体框架+高并发线程机制处理优化+提示词工程效果展示(按照框架自己修改可对接市面上百分之99的模型)
【Spring boot实战】Springboot+对话ai模型整体框架+高并发线程机制处理优化+提示词工程效果展示(按照框架自己修改可对接市面上百分之99的模型)
|
5月前
|
Java
java线程之分支合并框架
java线程之分支合并框架
|
6月前
|
安全 Java Spring
Spring框架中的单例Bean是线程安全的吗?
Spring框架中的单例Bean是线程安全的吗?
82 1
|
6月前
|
存储 NoSQL Java
12分钟从Executor自顶向下彻底搞懂线程池
12分钟从Executor自顶向下彻底搞懂线程池
|
4月前
|
设计模式 存储 安全
Java面试题:设计一个线程安全的单例类并解释其内存占用情况?使用Java多线程工具类实现一个高效的线程池,并解释其背后的原理。结合观察者模式与Java并发框架,设计一个可扩展的事件处理系统
Java面试题:设计一个线程安全的单例类并解释其内存占用情况?使用Java多线程工具类实现一个高效的线程池,并解释其背后的原理。结合观察者模式与Java并发框架,设计一个可扩展的事件处理系统
62 1
|
5月前
|
缓存 并行计算 Java
重温JAVA线程池精髓:Executor、ExecutorService及Executors的源码剖析与应用指南
重温JAVA线程池精髓:Executor、ExecutorService及Executors的源码剖析与应用指南
|
4月前
|
并行计算 安全 Java
线程操纵术并行策略问题之任务执行器(Executor)问题如何解决
线程操纵术并行策略问题之任务执行器(Executor)问题如何解决
|
4月前
|
设计模式 存储 缓存
Java面试题:结合建造者模式与内存优化,设计一个可扩展的高性能对象创建框架?利用多线程工具类与并发框架,实现一个高并发的分布式任务调度系统?设计一个高性能的实时事件通知系统
Java面试题:结合建造者模式与内存优化,设计一个可扩展的高性能对象创建框架?利用多线程工具类与并发框架,实现一个高并发的分布式任务调度系统?设计一个高性能的实时事件通知系统
57 0
|
4月前
|
设计模式 安全 NoSQL
Java面试题:结合单例模式与Java内存管理,设计一个线程安全的单例类?分析Java多线程工具类ExecutorService与Java并发工具包中的工具类,设计一个Java并发框架的分布式锁实现
Java面试题:结合单例模式与Java内存管理,设计一个线程安全的单例类?分析Java多线程工具类ExecutorService与Java并发工具包中的工具类,设计一个Java并发框架的分布式锁实现
64 0
|
4月前
|
设计模式 存储 缓存
Java面试题:结合单例模式与Java内存模型,设计一个线程安全的单例类?使用内存屏障与Java并发工具类,实现一个高效的并发缓存系统?结合观察者模式与Java并发框架,设计一个可扩展的事件处理系统
Java面试题:结合单例模式与Java内存模型,设计一个线程安全的单例类?使用内存屏障与Java并发工具类,实现一个高效的并发缓存系统?结合观察者模式与Java并发框架,设计一个可扩展的事件处理系统
39 0