在 "nested" `Mono` 的情况下,`flatMap` 和 `block` 之间有什么区别吗

Is there any difference between `flatMap` and `block` in case of "nested" `Mono`

据我了解,flatMapblock 都以 subscribe 结尾,那么下面的说法有什么不同吗?

Mono.just("a").flatMap(value -> Mono.just("b")).subscribe();
Mono.just("a").doOnNext(value -> Mono.just("b").block()).subscribe();

实际上,它们有很大的不同。第二个阻塞主线程。以下代码将阻塞主线程 5 秒:

@Test
void test_blockingCode() {
    Mono.just("a")
         .doOnNext(value -> Mono.just("b").delayElement(Duration.ofSeconds(5)).block())
         .subscribe();
    }

这是线程转储:

"main" #1 prio=5 os_prio=0 cpu=1550,32ms elapsed=4,41s tid=0x00007f376002c4e0 nid=0x2060 waiting on condition [0x00007f3768ae3000] java.lang.Thread.State: WAITING (parking) at jdk.internal.misc.Unsafe.$$BlockHound$$_park(java.base@16.0.2/Native Method)

  • parking to wait for <0x0000000611d97458> (a java.util.concurrent.CountDownLatch$Sync) at jdk.internal.misc.Unsafe.park(java.base@16.0.2/Unsafe.java) at java.util.concurrent.locks.LockSupport.park(java.base@16.0.2/LockSupport.java:211) at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(java.base@16.0.2/AbstractQueuedSynchronizer.java:714) at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(java.base@16.0.2/AbstractQueuedSynchronizer.java:1046) at java.util.concurrent.CountDownLatch.await(java.base@16.0.2/CountDownLatch.java:232) at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:87) at reactor.core.publisher.Mono.block(Mono.java:1704)