Spring webflux: flatmap asynchronous transformation
我读过平面图转换是异步的,在这个例子中,我在 lambda 定义中打印线程的名称。它正在打印订阅源的同一线程。根据我的理解,它应该打印一个不同的线程名称 - 除了订阅源之外,因为这个转换必须在不同的线程中执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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() |
它是异步的这一事实并不一定意味着它是并行运行的,这似乎是您在这里所期望的。但是,您可以将
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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. |
另一方面,如果您不希望它并行运行,而只是在主线程的单独线程上运行,则无需将其转换为并行
不,它不会打印不同的线程名称。默认情况下,响应式在单个线程上运行 - 订阅发生在该线程上。在这种情况下,订阅发生在调用线程上,因此,所有元素都在其上发出并在其上进一步处理。
让我们首先尝试了解 .
请注意,每个内部流毕竟是一个流。除非你告诉它使用不同的线程,否则每个线程都会在同一个线程上发出(调用线程,在你的情况下发生了什么)。如果您想并行处理它们,您可以为它们中的每一个执行
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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 的文章):
https://medium.com/swlh/understanding-reactors-flatmap-operator-a6a7e62d3e95
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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(); |
根据您想要的行为,您可以使用以下任何一种 -