【问题标题】:Is Mono.toFuture() blocking?Mono.toFuture() 是否阻塞?
【发布时间】:2019-10-22 12:39:18
【问题描述】:

来自Official Documentation of Mono#block()的消息是:

订阅此 Mono 并无限期阻止,直到收到下一个信号。返回该值,如果 Mono 完成为空,则返回 null。如果 Mono 错误,则抛出原始异常(如果是已检查异常,则将其包装在 RuntimeException 中)。

所以可以确定 block() 方法是阻塞的,直到block() 解决它才会执行下一行。

但我的困惑是,当我使用 toFuture() 时,我期望它是非阻塞的,但它的行为与 block 方法完全相同。在Documentation of Mono#toFuture() 中声明:

将此 Mono 转换为 CompletableFuture 在 onNext 或 onComplete 上完成并在 onError 上失败。

不太清楚。此文档中没有任何地方说 Mono#toFuture() 被阻止

  1. 请确认toFuture()方法是阻塞还是非阻塞?
  2. 另外如果是非阻塞那么,哪个线程将负责执行CompletableFuture里面的代码?

更新:添加代码 sn-p

使用Mono.block()方法:

    long time = System.currentTimeMillis();
    String block = Mono.fromCallable(() -> {
        logger.debug("inside in fromCallable() block()");
        //Upstream httpcall with apache httpClient().
        // which takes atleast 1sec to complete.
        return "Http response as string";
    }).block();
    logger.info("total time needed {}", (System.currentTimeMillis()-time));

    return CompletableFuture.completedFuture(block);

使用Mono.ToFuture()方法:

    long time = System.currentTimeMillis();
    CompletableFuture<String> toFuture = Mono.fromCallable(() -> {
        logger.debug("inside in fromCallable() block()");
        //Upstream httpcall with apache httpClient().
        // which takes atleast 1sec to complete.
        return "Http response as string";
    }).toFuture();
    logger.info("total time needed {}", (System.currentTimeMillis()-time));
    return toFuture;

这两个代码 sn-ps 的行为完全相同。

【问题讨论】:

  • 你能显示阻塞的代码吗?也许不是 toFuture 而是另一个阻塞的呼叫?
  • @Sweeper 我已经添加了示例代码sn-p,请检查。

标签: java reactive-programming apache-commons-httpclient reactor


【解决方案1】:

是的,你的怀疑是绝对正确的。实际上,Mono.block()Mono.toFuture() 会立即订阅并将您带出响应式系统。

这个官方Springblog post会让你更清楚。

我还建议通过Monosource code 显示blocktoFuture 立即订阅。

@ruhul 第一条评论的解释

您在序列之后放置.toFuture() 的行会导致代码阻塞。

所以,在下面的代码中

Mono.fromCallable(() -> {
        logger.debug("inside in fromCallable() block()");
        //Upstream httpcall with apache httpClient().
        // which takes atleast 1sec to complete.
        return "Http response as string";

    }).toFuture(); // this line is the blocking code.

当您遇到 toFuture() 时,就会开始订阅序列并且您的代码会脱离响应式上下文。

【讨论】:

  • 感谢您的回答。我之前也看到过这个答案,但尚未得到证实。虽然我们现在可以肯定了,但是请您详细说明一下,为什么会阻塞?哪一行代码实际上阻塞了整个事情。让来访的人都能轻松理解。
  • toFuture() 不会阻塞线程,而是返回可完成的未来,该未来将在通量完成后立即结束
猜你喜欢
  • 2020-09-16
  • 2011-04-09
  • 2017-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-02
  • 1970-01-01
  • 2023-03-13
相关资源
最近更新 更多