RxJava2订阅在一段时间后停止观察,但在flowable完成时继续

时间:2017-07-05 08:14:56

标签: rx-java rx-java2

我很难理解以下代码示例的行为;

    Flowable<String> f = Flowable.just(1)
            .flatMap(it -> Flowable.create(e -> {

                for(int i = 1; i < 1001; ++i) {
                    log.info("Emitting: " + i);
                    if(i % 10 == 0) {
                        Thread.sleep(1000);
                    }
                    e.onNext(i);
                }

                e.onComplete();
            }, BackpressureStrategy.BUFFER))
            .map(String::valueOf)
            .subscribeOn(Schedulers.io())
            .observeOn(Schedulers.newThread());

    f.subscribe(val -> {
        Thread.sleep(100);
        log.info("Observing: " + val);
    });

    Thread.sleep(1000000);

代码正常工作,直到subscribe电话观察到128个项目。发射和观察是平行的。但在此之后,Flowable继续发出物品(显然在某处排队)但在发出所有1000件物品之前没有观察到任何物品。在发出所有1000个项目之后,立即观察其余项目(> 128)。

这看起来与128的背压bufferSize有关,但我仍然期望发射和观察对于整个1000项是并行的,因为观察者显然不比发射器慢。这里有什么我想念的吗?我该怎么做来修复代码?

1 个答案:

答案 0 :(得分:3)

这是因为create和subscribeOn

之间存在同一个池死锁
  

如果链中有create(FlowableOnSubscribe, BackpressureStrategy)类型的源,建议使用subscribeOn(scheduler, false)来避免同一池死锁,因为请求可能会堆积在急切/阻塞的发射器后面。

//...
.subscribeOn(Schedulers.io(), false)
//...

修改

  

我尝试使用Flowable.range替换Flowable.create,但我没有遇到任何问题,我尝试了原始示例(以及建议的修复)。当问题可能发生时,你能举个例子吗?

Flowable.range(1, 10)
    .subscribeOn(Schedulers.io(), false)
    .doOnNext(v -> System.out.println(Thread.currentThread().getName()))
    .observeOn(Schedulers.single(), false, 1)
    .blockingSubscribe();

这最初打印RxCachedThreadScheduler-1然后RxSingleScheduler-1 9次,因为observeOn的补货请求将在单个调度程序上运行,而不是路由回io调度程序。请尝试使用subscribeOn true。