Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/370.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在发布程序完成之前触发时_Java_Project Reactor - Fatal编程技术网

Java 在发布程序完成之前触发时

Java 在发布程序完成之前触发时,java,project-reactor,Java,Project Reactor,示例代码: Flux<Integer> fluxSrc = Flux.<Integer> create(e -> { e.next(1); try { Thread.sleep(500); } catch (InterruptedException e1) { throw new RuntimeException(e1); } e.complete(); }) .publishOn(Schedulers

示例代码:

Flux<Integer> fluxSrc = Flux.<Integer> create(e -> {
   e.next(1);

   try {
      Thread.sleep(500);
   } catch (InterruptedException e1) {
      throw new RuntimeException(e1);
   }

   e.complete();
})
   .publishOn(Schedulers.single())
   .publish().autoConnect(2);

Flux<Integer> fluxA = fluxSrc
   .publishOn(Schedulers.single())
   .map(j -> 10 + j);

fluxA.subscribe(System.out::println);

Mono<Integer> monoB = fluxSrc
   .publishOn(Schedulers.single())
   .reduce(20, (j, k) -> {
      try {
         Thread.sleep(1000);
      } catch (InterruptedException e1) {
         throw new RuntimeException(e1);
      }
      return j + k;
   });

monoB.subscribe(System.out::println);

Mono.when(fluxA, monoB)
   .block();

System.out.println("After");
为什么它不等待两个发布者(
fluxA
monoB
)完成呢?我应该如何构造代码,以确保在到达
之后的
之前完成所有发布程序?

通过使用
.publish()
fluxSrc
变成热通量。考虑:

另一方面,热门出版商并不依赖于任何数量的 订户。他们可能会立即开始发布数据,并且 每当新订户进来时,继续这样做(在这种情况下 所述订户将只看到在其之后发射的新元素 订阅)。对于热门出版商来说,以前确实发生过一些事情 你订阅

()

解决这个问题的一种方法是摆脱
publish
,在冷流上运行。另一种是更改
.autoConnect(2)
自动连接(3)-这是因为您希望在第三次订阅时开始处理数据-
Mono.when(fluxA,monoB.block()已到达(前面的是
fluxA.subscribe
monoB.subscribe

编辑
确实在等待震源完成时,但它从先前的细分中得到了一个完整的信号

可能发生的情况是:

  • 通量A被
    fluxA.subscribe(System.out::println)所替代,发出11并打印它
  • 通量B被
    monoB.subscribe(System.out::println)所替代并开始还原
  • Mono。当
    被录制时(触发“多播”——流量被第二次录制)
  • 开始减少,结果将是21
  • 另一个减少开始并立即完成,结果为20(减少fluxSrc中的空流-仅项目已被另一个减少消耗)
  • 向两个订阅方发送一个完整的通量
  • 通量B发送完成,还原结果=20。它被传递到Mono制作的订阅。当
  • 时,这就是它没有被打印的原因
  • 自Mono.when subscription以来,两种通量均未完成发送,因此打印后
  • 大约在那个时候,第一次缩减完成,值为21,传递给
    monoB.subscribe(System.out::println)

  • 因此,
    fluxSrc
    是一个热门流量,可能在订阅
    block
    之前发布。你能解释一下为什么当
    不等待
    fluxA
    monoB
    完成时,这会导致
    ?这是因为比赛条件。如果您只是希望将“after”作为最后一条语句打印,那么必须同步reactor调度器和应用程序的线程。此外,一旦完成信号被广播到每个用户,在我的机器上,它看起来是这样的:完成通量a;完成单声道b;完成的通量仍然不能解释为什么
    不等待两个源完成时。反应流不是完全为了用户不必担心线程和竞争条件而生成的吗?让程序在执行
    线程时表现出不同的行为。在
    之前睡眠
    时并不真正令人鼓舞。不确定从何处获得步骤4和步骤8-减少会产生
    单声道
    ,因此它不能发射两次
    monoB
    最多会发出一个结果,它必须在完成之前发出,对吗?事实上,B必须在还原后完成-我更正了顺序。初始值为20,当前值为1的Mono的减少产生21,并完成Mono。将已完成的fluxSrc(Mono B的基础)的初始值减少为20会产生20。这意味着,在这种情况下,MonoB将只发射一个项目,但由于多个订阅方的多播,该多播项目的减少结果将有所不同。
    11
    After
    21