Reactor 是一个基于响应式编程的库,它提供了丰富的调度器(Schedulers)机制,用于管理异步操作的执行环境。Schedulers 是 Reactor 中的核心组件之一,它们允许开发者灵活地控制操作符和订阅操作在哪个线程上执行,从而实现高效的并发编程。


1. Schedulers 的作用

Schedulers 是 Reactor 提供的调度器接口,用于定义任务的执行上下文。它们封装了线程管理和调度逻辑,使得开发者可以专注于业务逻辑,而不是线程管理。Schedulers 的主要作用包括:

  • 控制任务的执行线程:通过指定不同的调度器,可以将任务分配到不同的线程或线程池中执行。
  • 支持异步编程:Schedulers 使得开发者可以轻松地在不同的线程中执行异步操作,从而实现并发。
  • 提供多种调度策略:Schedulers 提供了多种调度策略,如立即执行、单线程执行、弹性线程池、固定线程池等,以适应不同的应用场景。

2. 常见的 Schedulers

Reactor 提供了多种预定义的 Schedulers,每种调度器都有其特定的用途和特点:

Reactor 的 Schedulers 类提供了多种静态方法,用于创建和管理不同的执行上下文(Execution Context),这些上下文决定了任务在哪个线程或线程池中执行。以下是对你提供的内容的详细解释:


2.1. 无执行上下文(Schedulers.immediate()
  • 作用Schedulers.immediate() 是一个“无操作”调度器(no-op),它会在当前线程中直接执行提交的 Runnable

  • 特点

    • 任务不会被调度到其他线程,而是直接在当前线程中运行。
    • 适用于简单的同步操作或测试场景。
  • 示例

    Mono.just("Hello").subscribeOn(Schedulers.immediate()).subscribe(System.out::println);
    
    • 输出:Hello,且运行在当前线程中。
  • 引用


2. 2. 单线程执行器(Schedulers.single()
  • 作用Schedulers.single() 提供一个可重用的线程,所有调用者共享同一个线程,直到调度器被销毁。

  • 特点

    • 适合低延迟的一次性任务,如初始化操作。
    • 如果你需要为每个调用创建一个专用线程,应使用 Schedulers.newSingle()
  • 示例

    Mono.just("Hello").subscribeOn(Schedulers.single()).subscribe(System.out::println);
    
    • 输出:Hello,且运行在 Schedulers.single() 的线程中。
  • 引用


2. 3. 无界弹性线程池(Schedulers.elastic()
  • 作用Schedulers.elastic() 是一个动态线程池,根据需要创建新线程,复用空闲线程。

  • 特点

    • 适合处理长时间运行的任务,如 I/O 操作。
    • 但不再推荐使用,因为它可能导致线程过多,隐藏背压问题。
  • 示例

    Mono.just("Hello").subscribeOn(Schedulers.elastic()).subscribe(System.out::println);
    
    • 输出:Hello,且运行在 Schedulers.elastic() 的线程中。
  • 引用


2. 4. 有界弹性线程池(Schedulers.boundedElastic()
  • 作用Schedulers.boundedElastic() 是一个改进版的弹性线程池,它限制了线程数量,避免过多线程消耗资源。
  • 特点
    • 从 3.6.0 版本开始,支持两种实现:
  1. 基于 ExecutorService 的实现:线程数受限制(默认为 CPU 核心数 × 10),空闲线程在 60 秒后被销毁。
  2. 基于虚拟线程的实现:在 Java 21+ 环境中运行,每个任务使用一个新的 VirtualThread
  • 适用场景:适合 I/O 阻塞操作,避免占用过多系统资源。

  • 示例

    Mono.just("Hello").subscribeOn(Schedulers.boundedElastic()).subscribe(System.out::println);
    
    • 输出:Hello,且运行在 Schedulers.boundedElastic() 的线程中。
  • 引用


2. 5. 固定线程池(Schedulers.parallel()
  • 作用Schedulers.parallel() 创建一个固定大小的线程池,线程数通常等于 CPU 核心数。

  • 特点

    • 适合 CPU 密集型任务,如计算密集型操作。
    • Schedulers.boundedElastic() 一起使用,可以实现更精细的资源控制。
  • 示例

    Mono.just("Hello").subscribeOn(Schedulers.parallel()).subscribe(System.out::println);
    
    • 输出:Hello,且运行在 Schedulers.parallel() 的线程中。
  • 引用


2. 6. 自定义线程池(Schedulers.fromExecutorService(ExecutorService)
  • 作用:允许从现有的 ExecutorService 创建调度器。

  • 特点

    • 适用于需要自定义线程池的场景。
    • 可以灵活控制线程行为,如设置线程数、队列大小等。
  • 示例

    ExecutorService executor = Executors.newFixedThreadPool(4);
    Schedulers scheduler = Schedulers.fromExecutorService(executor);
    
  • 引用


2. 7. 调度器切换方法:publishOnsubscribeOn
  • subscribeOn

    • 用于指定整个流的订阅操作在哪个线程上执行。
    • 影响整个操作链的订阅行为。
  • publishOn

    • 用于指定后续操作符在哪个线程上执行。
    • 仅影响操作符链中的后续操作。
  • 示例

    Flux.just("A", "B", "C").subscribeOn(Schedulers.elastic()).map(String::toUpperCase).publishOn(Schedulers.parallel()).subscribe(System.out::println);
    
    • subscribeOn 指定了整个流的订阅线程,publishOn 指定了后续操作的执行线程。
  • 引用


2. 8. 总结
  • Schedulers 提供了多种调度器,用于控制任务的执行上下文。
  • Schedulers.immediate():直接在当前线程执行,适合简单任务。
  • Schedulers.single():共享一个线程,适合低延迟任务。
  • Schedulers.elastic()Schedulers.boundedElastic():动态线程池,适合 I/O 阻塞任务。
  • Schedulers.parallel():固定线程池,适合 CPU 密集型任务。
  • Schedulers.fromExecutorService():允许自定义线程池。
  • subscribeOnpublishOn:用于切换执行上下文,前者影响整个流,后者影响后续操作。

通过合理选择和使用这些调度器,可以实现高效的并发编程,优化任务的执行效率,并适应不同的应用场景。


3. Schedulers 的优势

  • 灵活性:Schedulers 提供了多种调度策略,允许开发者根据具体需求选择最合适的调度器。
  • 性能优化:通过合理选择调度器,可以优化任务的执行效率,减少资源消耗。
  • 并发控制:Schedulers 使得开发者可以灵活地控制任务的并发行为,从而实现更高效的异步编程。

4. Schedulers 的应用场景

  • IO 密集型任务:使用 Schedulers.elastic()Schedulers.boundedElastic() 来处理大量并发请求。
  • CPU 密集型任务:使用 Schedulers.parallel() 来处理计算密集型任务。
  • 测试和调试:使用 Schedulers.immediate() 来在当前线程中执行任务,便于调试。
  • 资源管理:通过 Schedulers.fromExecutorService() 自定义线程池,实现对资源的精细控制。

5. 总结

Reactor 的 Schedulers 是一个强大的工具,它允许开发者灵活地控制任务的执行环境。通过合理选择和使用 Schedulers,可以实现高效的异步编程,优化任务的执行效率,并适应不同的应用场景。Schedulers 的核心优势在于其灵活性和可配置性,使得开发者可以在不同的线程环境中执行任务,从而实现更高效的并发编程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/88987.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/88987.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/88987.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设备树引入

一、设备树的基本知识 1、什么是设备树?为什么会有设备树? 2011年,Linux之父Linus Torvalds发现这个问题后,就通过邮件向ARM-Linux开发社区发了一封邮件,不禁的发出了一句“This whole ARM thing is a f*cking pain i…

【数据标注师】3D标注

目录 一、 **3D标注知识体系框架**二、 **五阶能力培养体系**▶ **阶段1:空间认知筑基(2-3周)**▶ **阶段2:核心标注技能深化**▶ **阶段3:复杂场景解决方案**▶ **阶段4:领域深度专精▶ **阶段5&#xff1…

华为HN8145V光猫改华为蓝色公版界面,三网通用,xgpon公版光猫

咸鱼只卖20多元一个,还是xgpon的万兆猫,性价比不错哦 除了没有2.5G网口,其他还行。 改成公版光猫后,运营商是无法纳管光猫,无法后台修改光猫数据及超密。 华为 HN8145V 光猫具有以下特点: 性能方面 高速接…

【LeetCode 热题 100】438. 找到字符串中所有字母异位词——(解法二)定长滑动窗口+数组

Problem: 438. 找到字符串中所有字母异位词 题目:给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。 【LeetCode 热题 100】438. 找到字符串中所有字母异位词——(解法一&…

PAC 学习框架:机器学习的可靠性工程

PAC(Probably Approximately Correct) 是机器学习理论的核心框架,用于量化学习算法的可靠性。它回答了一个关键问题: “需要多少训练样本,才能以较高概率学到一个近似正确的模型?” 一、PAC 名称拆解 术语…

嵌入式C语言数组:数组/字符数组

1. 数组 1.1 一维数组 数组是一串连续的地址; 数组名是地址常量,代表数组的起始地址; sizeof(数组名) 可得出数组的总内存空间; C 语言对数组不做越界检查,使用时应注意; 数组不…

变长字节的数字表示法vb224

开始 数字有大有小,用多少字节表示呢? 本文描述的方案,采用变化的长度。vb是varying bytes的意思,224是表示它特征的一个数。 第一版: 每个字节8比特,最高的1比特用来表示“是否连续”,0表示…

ByteMD+CozeAPI+Coze平台Agent+Next搭建AI辅助博客撰写平台(逻辑清楚,推荐!)

背景: 现在主流的博客平台AI接入不够完善,如CSDN接入的AI助手不支持多模态数据的交互、稀土掘金的编辑器AI功能似乎还没能很好接入(哈哈哈,似乎在考虑布局什么?) 痛点分析: 用户常常以截图的形式…

【数据标注师】关键词标注

目录 一、 **理解关键词标注的核心逻辑**1. **三大标注原则**2. **关键词类型体系** 二、 **四阶训练体系**▶ **阶段1:基础规则内化**▶ **阶段2:语义浓缩训练**▶ **阶段3:场景化标注策略**▶ **阶段4:工具效率提升** 三、 **五…

for each循环语句

for each循环语句 for each.....nextFor Each 的案例 for each…next 1、循环对象合集 worksheets workbooks range range("区域")selection (选中的区域)usedrange或者currentregion 返回的单元格区域格式: for each 变量名 in 对象集合(范围)循环内容…

基于LQR控制器的六自由度四旋翼无人机模型simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序 4.系统原理简介 5.参考文献 6.完整工程文件 1.课题概述 四旋翼无人机因其结构简单、机动性强和成本低廉等特点,在航拍测绘、物流运输、灾害救援等领域得到广泛应用。六自由度(3维平移3维旋转&#xff0…

vftp centos 离线部署

install_ftp_offline.sh vsftpd-3.0.2-28.el7.x86_64.rpm #!/bin/bash# 一键安装配置vsftpd脚本(开放根目录,禁用chroot)# 安装vsftpd RPM包 echo "正在安装vsftpd..." rpm -ivh vsftpd-3.0.2-28.el7.x86_64.rpm if [ $? -ne 0 …

【数据标注】事件标注1

目录 **一、 深入理解事件标注的核心概念****二、 系统学习:从理论到实践****1. 吃透标注指南****2. 语言学基础补充****3. 事件结构解析训练** **三、 分阶段实践:从简单到复杂****阶段1:基础标注训练****阶段2:进阶挑战****阶段…

在 Ansys Electronics Desktop 中启用额外的 CPU 内核和 GPU

Ansys Electronics Desktop (AEDT) 可以通过利用多个 CPU 内核和 GPU 加速来显著缩短仿真时间。但是,启用其他计算资源除了基本求解器许可证外,还需要适当的高性能计算 (HPC) 许可证。 默认情况下,基本许可证最多允许使用 4 个内核,而无需任何其他 HPC 许可。借助 Ans…

R语言机器学习算法实战系列(二十六)基于tidymodels的XGBoost二分类器全流程实战

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍加载R包数据准备数据探索转换因子查看属性相关性配对图PCA 可视化缺失值、异常值处理 & 特征标准数据分割构建模型与调参模型评估模型可解释性(变量重要性、SHAP、DALEX)变量…

零基础langchain实战一:模型、提示词和解析器

一,使用python调取大模型api 1,获取api_key 获取api_key 在各个大模型的官网中获取。 2,设置api_key 方式一: 在系统环境中可直接执行python代码:这里以deepseek为例 import os os.environ["DEEPSEEK_API_…

Pytorch分布式通讯为什么要求Tensor连续(Contiguous)

参考资料: https://github.com/pytorch/pytorch/issues/73515 https://www.cnblogs.com/X1OO/articles/18171700 由于业务原因,需要在Pytorch代码中使用分布式通讯来把计算负载平均到多张显卡上。在无数次确认我的业务代码没问题之后,我开始把…

关于前端页面上传图片检测

依赖于前文,linux系统上部署yolo识别图片,远程宿主机访问docker全流程(https://blog.csdn.net/yanzhuang521967/article/details/148777650?spm1001.2014.3001.5501) fastapi把端口暴露出来 后端代码 from fastapi import FastAPI, UploadFile, File, HTTPExcep…

第十三章---软件工程过程管理

仅供参考 文章目录 一、Gantt图是做什么的。二、软件配置的概念 一、Gantt图是做什么的。 Gantt 图(甘特图)是软件项目管理中用于进度安排和可视化管理的重要工具,主要用于展示任务的时间安排、进度状态及任务之间的依赖关系 Gantt 图是一种…

多模态大语言模型arxiv论文略读(140)

SemiHVision: Enhancing Medical Multimodal Models with a Semi-Human Annotated Dataset and Fine-Tuned Instruction Generation ➡️ 论文标题:SemiHVision: Enhancing Medical Multimodal Models with a Semi-Human Annotated Dataset and Fine-Tuned Instruc…