简体   繁体   English

Reactor - 异步/非阻塞

[英]Reactor - Async / non-blocking

I thought below flux chain will be placed / executed via event loop (like JS).我认为下面的通量链将通过事件循环(如 JS)放置/执行。 So running the below code will print the blocking for loop first & then flux chain will be executed.因此,运行以下代码将首先打印阻塞for循环,然后执行通量链。

But the entire flux is executed first always before it moves to for loop.但是整个通量总是在它移动到for循环之前首先执行。 [I do have some sleep statements which is blocking. [我确实有一些阻塞的sleep语句。 But there are in 2 doOnNext stages]但是有 2 个doOnNext阶段]

AtomicInteger atomicInteger = new AtomicInteger(0);

// reactor
Flux.generate(synchronousSink -> {
            if (atomicInteger.incrementAndGet() < 3) {
                synchronousSink.next(atomicInteger.get());
            } else
                synchronousSink.complete();
    })
    .doOnNext(i -> {
        System.out.println(
                "A - Received " + i + " by " + Thread.currentThread().getName()
        );
        sleep(Duration.ofSeconds(1));
    }).doOnNext(i -> {
        System.out.println(
                "B - Received " + i + " : by " + Thread.currentThread().getName()
        );
        sleep(Duration.ofSeconds(1));
    }).subscribe();


for (int i = 0; i < 5; i++) {
    System.out.println("For " + i + " by " + Thread.currentThread().getName());
    sleep(Duration.ofMillis(500));
}

It prints它打印

A - Received 1 by main
B - Received 1 by main
A - Received 2 by main
B - Received 2 by main
For 0 by main
For 1 by main
For 2 by main
For 3 by main
For 4 by main

Could someone please explain this behavior and answer these questions?有人可以解释这种行为并回答这些问题吗?

  1. Only way to achieve async/non-blocking behavior by using some schedulers when we use reactor?当我们使用反应器时,通过使用一些调度程序来实现异步/非阻塞行为的唯一方法是什么?
  2. If I am not using any schedulers and let the code use the current thread for execution, can we expect any better performance difference using WebFlux instead of Spring MVC even for an IO intensive applications?如果我不使用任何调度程序并让代码使用当前线程执行,即使对于 IO 密集型应用程序,我们是否可以期望使用 WebFlux 而不是 Spring MVC 获得更好的性能差异?
  1. Thread blocking is not proper usage of Reactor usage.线程阻塞不是 Reactor 使用的正确用法。 To make it work in a non-blocking way you should use publishOn / subscribeOn then the output should be:要使其以非阻塞方式工作,您应该使用publishOn / subscribeOn然后 output 应该是:
 For 0 by main A - Received 1 by boundedElastic-3 For 1 by main For 2 by main B - Received 1: by boundedElastic-3 For 3 by main For 4 by main A - Received 2 by boundedElastic-3

For more about publishOn vs subscribeOn see: link有关publishOnsubscribeOn的更多信息,请参见: 链接

  1. For sure - Reactor support non-blocking for HTTP (including Websockets), TCP, and UDP.当然 - Reactor 支持 HTTP(包括 Websockets)、TCP 和 UDP 的非阻塞。 What's more Reactor as a default works on Netty server, which changes the way how the requests are handled.更重要的是 Reactor 作为默认的工作在 Netty 服务器上,它改变了请求的处理方式。 For example in Tomcat request-response is handled by same thread - what is more this thread is waiting for a response, so it is blocked.例如在 Tomcat 中,请求-响应由同一个线程处理——更重要的是,这个线程正在等待响应,所以它被阻塞了。 In Netty, the one thread can handle sending request and the other can handle receiving a response - threads are not waiting implicit for a response.在 Netty 中,一个线程可以处理发送请求,另一个可以处理接收响应——线程不会隐式等待响应。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM