Java 弹簧反应器螺纹模型

Java 弹簧反应器螺纹模型,java,spring,spring-webflux,project-reactor,Java,Spring,Spring Webflux,Project Reactor,SpringWebFlux的新手警报(v2.0.1版本) 我希望将SpringWebFlux用于后端(无Web)应用程序,以处理来自JMS侦听器的大量数据 我的理解是SpringWebFlux提供了一个非阻塞/异步并发模型。然而,我有一个基本的问题,我需要一些帮助。作为免责声明,反应式编程的整个概念对我来说是非常新的,我仍然处于这种范式转换的过程中 考虑以下代码: Mono.just("ONE") .map(item -> func(" A " + item)) .map(item -&g

SpringWebFlux的新手警报(v2.0.1版本)

我希望将SpringWebFlux用于后端(无Web)应用程序,以处理来自JMS侦听器的大量数据

我的理解是SpringWebFlux提供了一个非阻塞/异步并发模型。然而,我有一个基本的问题,我需要一些帮助。作为免责声明,反应式编程的整个概念对我来说是非常新的,我仍然处于这种范式转换的过程中

考虑以下代码:

Mono.just("ONE")
.map(item -> func(" A " + item))
.map(item -> func(" B " + item))
.map(item -> func(" C " + item))
.subscribe(System.out::println);

Mono.just("TWO")
.map(item -> func(" A " + item))
.map(item -> func(" B " + item))
.map(item -> func(" C " + item))
.subscribe(System.out::println);
我从文档中了解到,在调用“订阅”功能之前,事件处理链不会发生任何变化

但是在内部,spring是否(如果愿意的话)为“map”函数中的每个函数异步使用单独的线程?如果spring为这些链使用“单”线,那么这里的真正用途是什么?它不是基于不同语法的阻塞单线程模型吗


我注意到代码总是按顺序运行,并且使用相同的线程。SpringWebFlux的线程模型是什么

TL;医生:

  • 这是一个项目反应器,SpringWebFlux不决定在哪个线程上运行什么操作
  • ProjectReactor可以更容易地告诉您跨越线程边界的位置。而且,没有(显式)同步进行;使引入并发问题变得更加困难 不,它不是具有不同语法的单线程模型。ProjectReactor尽可能多地使用主线程来避免上下文切换。此外,它还提供了特殊的运算符,允许您指定以前的操作在其上运行的线程

    例如,这个修改后的示例将在不同的线程上运行;as
    subscribeOn
    运算符定义整个链运行在哪个线程池上:

    Mono.just("ONE")
        .map(item -> func(" A " + item))
        .map(item -> func(" B " + item))
        .map(item -> func(" C " + item))
        .subscribeOn(Schedulers.elastic())
        .subscribe(item -> {
            System.out.println(Thread.currentThread().getName() + " " + item);
        });
    
    Mono.just("TWO")
        .map(item -> func(" A " + item))
        .map(item -> func(" B " + item))
        .map(item -> func(" C " + item))
        .subscribeOn(Schedulers.elastic())
        .subscribe(item -> {
            System.out.println(Thread.currentThread().getName() + " " + item);
        });
    

    在这种情况下,两个操作都在
    elastic-x
    线程上执行;没有阻塞主线程。每次运行的操作顺序可能会有所不同。

    反应式编程是一种编程范式,因此它不会对技术实现做出任何假设

    描述反应式系统,并将异步通信和背压带到桌面上。除此之外,它也没有对技术细节做出任何假设

    Webflux反应堆的弹簧反应堆,是一个允许您轻松构建反应系统并遵循反应式编程范例的库。

    流使用的线程取决于发布服务器。默认情况下使用当前线程。如果发布服务器是同步的,则在没有任何干预的情况下,流不能是异步的。如果发布服务器阻止,则流将被阻止。但以下面的例子为例:

    Flux.interval(Duration.ofMillis(100))
        .take(2)
        .subscribe(i -> System.out.println(Thread.currentThread().getName()));
    
    Flux.interval
    在另一个线程上发布,因此链在另一个线程中异步运行

    让我们看另一个例子:

    Scheduler scheduler = Schedulers.newElastic("foo");
    
    Flux<Integer> flux = Flux.just(1, 2)
        .subscribeOn(scheduler);
    
    flux.subscribe(i -> System.out.println(Thread.currentThread().getName()));
    flux.subscribe(i -> System.out.println(Thread.currentThread().getName()));
    
    Scheduler=Schedulers.newElastic(“foo”);
    通量通量=通量。仅(1,2)
    .subscribeOn(调度程序);
    订阅(i->System.out.println(Thread.currentThread().getName());
    订阅(i->System.out.println(Thread.currentThread().getName());
    
    您会注意到,每个订阅服务器都在自己的线程上运行(尽管来自同一个线程池)。
    publishOn
    操作符与此类似

    如果订阅发布服务器,则无论是同步还是异步,都可以使用相同的编程范例。您可以通过添加
    subscribeOn
    publishOn
    操作符来引入异步行为