首页 文章

Reactor Mono vs CompletableFuture

提问于
浏览
5

刚开始探索反应堆项目及其抽象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() 函数中打印的线程名称是主线程 . 所以我看到顺序/阻塞行为而不是顺序/非阻塞(异步)行为 . 是因为我在同一个线程上应用了一个订阅函数,它是阻塞的吗?有人可以解释一下吗?

1 回答

  • 3

    是因为我在同一个线程上应用了一个订阅函数,它是阻塞的吗?

    这正是似乎发生的事情 .

    这种特殊的行为让我感到惊讶,因为它不是大多数管道行为的方式 . 大多数管道都有这样或那样的一些操作,使管道异步 . publishOnsubscribeOn 是明显的例子,但也是flatMap might have such an effect,可能还有很多其他例子 . 在这些情况下,订阅将立即返回 .

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

相关问题