0

0

如何在 Spring Reactor 中实现真正非阻塞的延迟模拟

心靈之曲

心靈之曲

发布时间:2026-01-30 09:18:20

|

303人浏览过

|

来源于php中文网

原创

如何在 Spring Reactor 中实现真正非阻塞的延迟模拟

本文详解如何使用 reactor 的 `mono.delay()` 和 `concatmap` 等操作符,在不调用 `thread.sleep()`、不触发线程阻塞的前提下,模拟耗时但完全非阻塞的业务逻辑,满足 blockhound 检测要求。

响应式编程中,Thread.sleep() 是典型的阻塞反模式——它会使当前线程挂起,浪费调度资源,违背 Reactor “单线程高效复用”的设计哲学。BlockHound 会直接报错:Blocking call! java.lang.Thread.sleep。因此,真正的非阻塞延迟必须依赖 Reactor 内置的基于时间调度器(Scheduler)的异步延迟机制,而非线程休眠。

核心思路是:将“耗时操作”建模为一个 Mono,利用 Mono.delay() 触发定时信号,并通过 concatMap(或 flatMap,视并发需求而定)将其无缝集成到上游流中。delay() 底层使用 Schedulers.parallel() 或指定 Scheduler,仅注册定时任务,不占用工作线程,全程无阻塞。

以下是符合要求的正确实现:

@Test
public void simulateLengthyProcessingOperationReactor() {
    Flux.range(1, 5000)
        .concatMap(this::simulateDelay_NON_blocking) // 串行执行,保持顺序
        .subscribe(
            System.out::println,
            error -> System.err.println("Error: " + error),
            () -> System.out.println("Completed!")
        );
}

public Mono simulateDelay_NON_blocking(Integer input) {
    return Mono.delay(Duration.ofMillis(4000)) // 非阻塞定时:4秒后发出空信号
               .map(unused -> String.format(
                   "[%d] on thread [%s] at time [%s]",
                   input,
                   Thread.currentThread().getName(),
                   new Date()
               ));
}

关键点解析:

通义万相
通义万相

通义万相,一个不断进化的AI艺术创作大模型

下载
  • Mono.delay(Duration) 返回一个 Mono,在指定延时后发出 onNext(null) 和 onComplete(),不阻塞任何线程
  • concatMap 确保每个 simulateDelay_NON_blocking 调用按序执行(适合模拟串行长任务),若需并行可换用 flatMap 并指定并发数(如 .flatMap(this::simulateDelay_NON_blocking, 32));
  • 所有时间调度由 Reactor 默认的 parallel Scheduler(基于 ForkJoinPool)完成,主线程(如 main 或 elastic)不会被阻塞;
  • 此实现能顺利通过 BlockHound 检测,日志中线程名将显示为 parallel-*,而非 main 或业务线程被长期占用。

⚠️ 注意事项:

  • ❌ 不要尝试在 map() 中调用 delay() —— map 是同步转换操作符,无法处理返回 Mono 的异步逻辑;必须使用 flatMap/concatMap 等组合型操作符
  • ❌ 避免在 delay() 后使用 block() 或 toFuture().get() —— 这会重新引入阻塞;
  • ✅ 如需更精细控制调度器(例如隔离 IO 延迟),可显式传入:Mono.delay(Duration.ofSeconds(4), Schedulers.boundedElastic());
  • ? 验证是否真正非阻塞:启动 BlockHound(BlockHound.install())后运行测试,无异常即通过。

总结:Reactor 中模拟“非阻塞长耗时操作”的标准范式是 Mono.delay().map(...) + concatMap/flatMap。它既满足语义上“等待 X 时间再继续”的业务需求,又严格遵循响应式契约——零线程阻塞、全异步调度、资源高效复用。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
spring框架介绍
spring框架介绍

本专题整合了spring框架相关内容,想了解更多详细内容,请阅读专题下面的文章。

115

2025.08.06

Java Spring Security 与认证授权
Java Spring Security 与认证授权

本专题系统讲解 Java Spring Security 框架在认证与授权中的应用,涵盖用户身份验证、权限控制、JWT与OAuth2实现、跨站请求伪造(CSRF)防护、会话管理与安全漏洞防范。通过实际项目案例,帮助学习者掌握如何 使用 Spring Security 实现高安全性认证与授权机制,提升 Web 应用的安全性与用户数据保护。

32

2026.01.26

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

236

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

458

2024.03.01

javascriptvoid(o)怎么解决
javascriptvoid(o)怎么解决

javascriptvoid(o)的解决办法:1、检查语法错误;2、确保正确的执行环境;3、检查其他代码的冲突;4、使用事件委托;5、使用其他绑定方式;6、检查外部资源等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

177

2023.11.23

java中void的含义
java中void的含义

本专题整合了Java中void的相关内容,阅读专题下面的文章了解更多详细内容。

98

2025.11.27

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

503

2023.08.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

503

2023.08.10

java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

1

2026.01.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 4.3万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1.0万人学习

React核心原理新老生命周期精讲
React核心原理新老生命周期精讲

共12课时 | 1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号