RxJava Flowable缓存到单个死锁

时间:2019-10-18 23:15:52

标签: java java-8 rx-java rx-java2 reactive-streams

下面是我的代码段。

我知道您不应该这样阻塞cachedFlowable,但这只是一个例子。

它停留在blockingGet行。

如果我将singleOrError替换为singleElement,代码仍然会卡住。如果我将singleOrError替换为firstElement,代码将不再卡住。

有人可以向我解释为什么会这样吗?

    public static void main(String[] args) {
        final Flowable<Integer> cachedFlowable = Flowable.just(1).cache();
        cachedFlowable
                .doOnNext(i -> {
                    System.out.println("doOnNext " + i);
                    final Integer j = cachedFlowable.singleOrError().blockingGet();
                    System.out.println("after blockingGet " + j);
                })
                .blockingSubscribe();
    }

1 个答案:

答案 0 :(得分:2)

它与singleX运算符陷入僵局的原因是,此类运算符等待第二项可能的发出,但是由于您正在阻止它们,因此无法执行主源中的任何第二项或补全。使用firstX,他们只关心第一个项目,因此几乎立即取消阻止,从而使源可以完成。

因此,是的,您不应该在这样的流中使用阻塞方法,而应使用flatMapconcatMap来执行每项子流:

var cache = Flowable.just(1).cache();

cache
.doOnNext(i -> System.out.println("doOnNext " + i))
.concatMapSingle(item -> cache.firstOrError())
.doOnNext(j -> System.out.println("after " + j))
.blockingSubscribe();