【问题标题】:Reactor Mono vs CompletableFutureReactor Mono vs CompletableFuture
【发布时间】:2017-11-30 10:37:49
【问题描述】:

刚开始探索 reactor 项目及其抽象 Mono 和 Flux,想了解与 Java 8 准系统 CompletableFuture 的基本区别。

这是我的一个简单代码:

public static void main(String[] args) throws Exception {

    Mono.fromCallable(() -> getData())
            .map(s -> s + " World ")
            .subscribe(s -> System.out.println(s));

    CompletableFuture.supplyAsync(() -> getData())
            .thenAccept(System.out::println);

    System.out.println(Thread.currentThread()+" End ");
}

private static String getData() {

    int j=0;

    for(int i=0; i<Integer.MAX_VALUE; i++){
        j = j - i%2;
    }

    System.out.println(Thread.currentThread()+" - "+j);
    return " Hello ";
}

首先,CompletableFuture 并不令人意外。 supplyAsync 通过 ForkJoinPool 安排函数执行,“End”行立即打印,程序终止,因为主线程在这里真的很短暂 - 正如预期的那样。

但是Mono.fromCallable(...) 阻塞了那里的主线程。此外,getData() 函数中打印的线程名称是主线程。所以我看到了顺序/阻塞行为,而不是顺序/非阻塞(异步)行为。是因为我在同一个线程上应用了订阅函数,它被阻塞了吗?有人可以解释一下吗?

【问题讨论】:

    标签: spring java-8 project-reactor spring-webflux


    【解决方案1】:

    是不是因为我在同一个线程上应用了订阅函数,所以阻塞了?

    这正是似乎发生的事情。

    这个特定的行为让我有点吃惊,因为它不是大多数管道的行为方式。大多数管道都有一种或另一种使管道异步的操作。 publishOnsubscribeOn 是明显的例子,但也有 flatMap might have such an effect 和可能许多其他例子。在这些情况下,订阅将立即返回。

    这暗示了关于反应式编程的一个非常重要的点:管道不应该包含长阻塞调用。反应式管道旨在准备好并在订阅时处理事件而不会阻塞。因此,阻塞语句具有阻塞整个执行的真正潜力。通过使用Scheduler,您可以将此类调用限制在特殊的线程池中,从而控制它们的效果。

    【讨论】:

      猜你喜欢
      • 2019-07-18
      • 2021-11-23
      • 2020-08-07
      • 2016-12-09
      • 2019-02-17
      • 1970-01-01
      • 2019-06-06
      • 2022-10-24
      • 1970-01-01
      相关资源
      最近更新 更多