簡體   English   中英

Reactor - 異步/非阻塞

[英]Reactor - Async / non-blocking

我認為下面的通量鏈將通過事件循環(如 JS)放置/執行。 因此,運行以下代碼將首先打印阻塞for循環,然后執行通量鏈。

但是整個通量總是在它移動到for循環之前首先執行。 [我確實有一些阻塞的sleep語句。 但是有 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));
}

它打印

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

有人可以解釋這種行為並回答這些問題嗎?

  1. 當我們使用反應器時,通過使用一些調度程序來實現異步/非阻塞行為的唯一方法是什么?
  2. 如果我不使用任何調度程序並讓代碼使用當前線程執行,即使對於 IO 密集型應用程序,我們是否可以期望使用 WebFlux 而不是 Spring MVC 獲得更好的性能差異?
  1. 線程阻塞不是 Reactor 使用的正確用法。 要使其以非阻塞方式工作,您應該使用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

有關publishOnsubscribeOn的更多信息,請參見: 鏈接

  1. 當然 - Reactor 支持 HTTP(包括 Websockets)、TCP 和 UDP 的非阻塞。 更重要的是 Reactor 作為默認的工作在 Netty 服務器上,它改變了請求的處理方式。 例如在 Tomcat 中,請求-響應由同一個線程處理——更重要的是,這個線程正在等待響應,所以它被阻塞了。 在 Netty 中,一個線程可以處理發送請求,另一個可以處理接收響應——線程不會隱式等待響應。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM