将阻塞代码包装到Mono flatMap中,这还是非阻塞操作吗?

iSm*_*Smo 4 spring nonblocking blocking reactor reactive-programming

如果我将阻塞代码包装到 flatMap 中,这仍然是非阻塞操作吗?

例子:

    public Mono<String> foo() {

    Mono.empty().flatMap(obj -> {

        try {

        Object temp = f.get();//are the thread at this point blocked or not ?

        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }

        return Mono.just("test");

    });
Run Code Online (Sandbox Code Playgroud)

所以,我认为当我将阻塞代码包装到反应式代码中时,操作仍然是非阻塞的?如果我错了,请向我解释。

Yaz*_*ber 6

如果我将阻塞代码包装到 flatMap 中,这仍然是非阻塞操作吗?

flatMap 不会为您创建新线程。例如:

Mono.just("abc").flatMap(val -> Mono.just("cba")).subscribe();
Run Code Online (Sandbox Code Playgroud)

上面的所有代码都将由调用 的当前线程执行subscribe。因此,如果映射器函数包含长阻塞操作,则调用 subscribe 的线程也将被阻塞。

要将其转换为异步操作,您可以使用subscribeOn(Schedulers.elastic());

 Mono.just("abc").flatMap(val -> Mono.just("cba")).subscribeOn(Schedulers.elastic());
Run Code Online (Sandbox Code Playgroud)

Mono 和 Flux 不创建线程,但某些运算符Scheduler作为额外的参数来使用,例如interval运算符,或者一起更改线程模型,例如subscribeOn.

一件额外的事情,在您的示例中,映射器函数永远不会被调用,因为您将 flatMap 应用于一个空的单声道,它直接完成而没有发出任何值。