我已经阅读了Flatmap转换是异步的,在此示例中,我正在lambda定义内打印线程的名称。它正在打印与订阅源相同的线程。根据我的理解,它应该打印不同的线程名称-除了已预订源的线程名称以外,因为此转换必须在不同的线程中执行。
Flux.just(1, -2, 3, 4, -5, 6)
.flatMap(element -> {
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " element: " + element);
return Flux.just(element);
})
.subscribe()
答案 0 :(得分:1)
它是异步的事实并不一定意味着它在 parallel 中运行,这似乎是您期望的。但是,您可以将Flux
转换为ParallelFlux
并指定并行调度程序:
Flux.just(1, -2, 3, 4, -5, 6)
.parallel()
.runOn(Schedulers.elastic())
.flatMap(element
-> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) { // TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()
+ " element: " + element);
return Flux.just(element);
})
.subscribe();
Thread.currentThread().join(); //Just a hack to keep the program alive.
另一方面,如果您不希望它并行运行,而只是在与主线程不同的线程上运行,则无需将其转换为并行的Flux
-只需提供一个{ {1}}电话或类似电话。
答案 1 :(得分:1)
否,它不会输出其他线程名称。默认情况下,反应式在单个线程上运行-发生订阅。在这种情况下,预订发生在调用线程上,因此,所有元素都在该线程上发出并在该线程上进行进一步处理。
让我们首先尝试了解。flatMap
的工作原理:
flatMap
急切地订阅每个内部流(这就是为什么它们被触发的原因)。请注意,这里急切的意思是它立即订阅所有内部流,而无需等待其他内部流完成(与concatMap
不同)。请注意,每个内部流毕竟是一个流。除非您告诉它使用不同的线程,否则每个线程都将在同一线程上发出(调用线程,您所发生的情况)。如果要并行处理它们,可以对它们每个进行.subscribeOn(Schedulers.elastic)
(或schedulers.parallel()
)操作:
Flux.just(1, -2, 3, 4, -5, 6)
.flatMap(
element -> {
//this will always print the same thread - the calling thread basically
System.out.println(Thread.currentThread().getName() + " element: " + element);
return Mono.just(element)
.subscribeOn(Schedulers.parallel())
.doOnNext(
a ->
System.out.println(
a + " emitted on thread: " + Thread.currentThread().getName()));
})
.subscribe();
。flatMap
不在乎元素进入哪个线程,什么线程退出-它所要做的就是订阅内部流并在事件出现时合并它们的事件。请记住,每个内部流都是一个“承诺”。它最终将完成(带有onComplete
)信号,但是您不知道何时。 flatMap
仍然不在乎。 concatMap
但是,在订阅下一个流之前先等待流完成。这样便可以保持原始流的顺序。
在此阅读更多信息(我在flatMap上的文章):
https://medium.com/swlh/understanding-reactors-flatmap-operator-a6a7e62d3e95
答案 2 :(得分:0)
使用flatMap
不会影响其执行的线程。您可以使用subscribeOn
影响将在其上执行的线程:
Flux.just(1, -2, 3, 4, -5, 6)
.flatMap(element ->
{
try { Thread.sleep(1000);
} catch (InterruptedException e) { // TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() +
" element: " + element);
return Flux.just(element);
})
.subscribeOn(Schedulers.elastic())
.subscribe();
根据您想要的行为,可以使用以下任何一种-
Schedulers.elastic()
,Schedulers.single()
,Schedulers.parallel()
,Schedulers.immeadiate()