Reactor 中 Mono.just() 的执行时机与非阻塞实践详解

大明姑娘_4832

大明姑娘_4832

2026-07-05

934人浏览

原创

Mono.just() 在链构建阶段即同步执行参数计算,无法延迟或异步化阻塞逻辑;要实现真正非阻塞,应改用 Mono.fromCallable() 并配合真正的异步操作(如 delayElement),而非在 just() 中嵌入 sleep() 等阻塞调用。

reactor 中 `mono.just()` 在链构建阶段即同步执行参数计算,无法延迟或异步化阻塞逻辑;要实现真正非阻塞,应改用 `mono.fromcallable()` 并配合真正的异步操作(如 `delayelement`),而非在 `just()` 中嵌入 `sleep()` 等阻塞调用。

在响应式编程中,一个常见误区是认为只要将代码“包装进 Mono 或 Flux”,就能自动变为非阻塞。事实恰恰相反:Reactor 不会魔法般地将阻塞调用转为非阻塞。它仅提供调度、编排和背压能力,底层执行仍依赖实际操作的性质——若内部含 Thread.sleep()、JDBC 同步调用或文件 I/O,线程依然会被挂起。

? 问题核心:Mono.just() 的执行时机

Mono.just(value) 是立即求值(eager evaluation) 的操作符:它在创建 Publisher 的瞬间就执行 value 的计算(如调用 getString()),且该计算发生在当前线程(通常是主线程),而非订阅后指定的调度器线程。因此:

Mono.just(getString()) // ← getString() 在此处同步阻塞主线程!
    .subscribeOn(Schedulers.parallel())
    .subscribe(...);

即使后续指定了 subscribeOn(Schedulers.parallel()),也已无法“撤回” getString() 的阻塞——它早已在链组装时完成。这正是你第二个测试中循环逐次等待、输出顺序出现的根本原因。

✅ 正确做法:使用 Mono.fromCallable()
该操作符将计算逻辑延迟到订阅时执行,并可由调度器控制执行线程:

Mono.fromCallable(() -> getString()) // getString() 延迟到 subscribe 阶段,在 parallel 线程中执行
    .subscribeOn(Schedulers.parallel())
    .map(s -> {
        System.out.println("Thread: " + Thread.currentThread().getName() + " → " + s);
        return s.length();
    })
    .subscribe(System.out::println);

⚠️ 注意:这仍未消除阻塞!getString() 内的 sleep(2000) 依然会阻塞 parallel-1、parallel-2 等工作线程。在生产环境中,这将迅速耗尽线程池,导致吞吐量崩溃。

react-best-practices
react-best-practices

重要:对 React 或 Next.js 代码的任何更改必须先阅读本技能。Vercel 工程团队的 React 与 Next.js 指南,涵盖可视化...

下载

✅ 真正非阻塞的替代方案

要模拟异步延迟(如 HTTP 请求、数据库查询),必须使用非阻塞原语,例如:

  • Mono.delay(Duration):基于时间轮(HashedWheelTimer)的轻量级定时,不占用线程;
  • Mono.fromFuture() + CompletableFuture.supplyAsync()(需谨慎,仍可能用到线程池);
  • 优先采用真正的非阻塞驱动:如 R2DBC(数据库)、WebClient(HTTP)、Netty(网络)。

示例(推荐):

public static Mono<string> getStringAsync() {
    return Mono.delay(Duration.ofSeconds(2)) // 非阻塞延迟
                .thenReturn("Hello world");   // 延迟后发出值
}

// 使用方式
for (int i = 0; i  {
            System.out.println(Instant.now() + " | Thread: " + 
                Thread.currentThread().getName() + " | " + s);
            return s.length();
        })
        .subscribeOn(Schedulers.parallel())
        .subscribe(len -> System.out.println("Length: " + len));

    System.out.println(Instant.now() + " | Loop: " + i + " → after MONO");
}</string>

输出将显示所有 "after MONO" 几乎同时打印,随后约 2 秒后批量输出处理结果——证明整个流程真正非阻塞。

? 关键总结

操作符 执行时机 是否支持异步 适用场景
Mono.just(value) 创建时立即计算 value ❌(阻塞在链构建阶段) 已知、快速、无副作用的常量值
Mono.fromCallable(() -> heavyWork()) 订阅时在指定 Scheduler 执行 ⚠️(可调度线程,但逻辑仍阻塞) 必须使用阻塞 API 且需隔离线程时(如遗留系统集成)
Mono.delay().thenReturn() / Mono.fromFuture() 异步触发,不阻塞线程 ✅ 模拟延迟、对接非阻塞生态

? 最佳实践:永远避免在 just()、fromSupplier() 等 eager 操作符中放入耗时或阻塞逻辑;对 I/O 密集型操作,坚持使用 Reactor 原生非阻塞 API(如 WebClient, R2DBC),而非试图“包装阻塞代码”。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

react

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

9997

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

7142

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

6292

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

1084

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

908

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1316

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2629

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

19951

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

1175

8

热门下载

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

精品课程

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

共58课时 | 12.1万人学习

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

共12课时 | 1.4万人学习