RxJava的onBackpressureDrop()会丢弃项目吗?

时间:2016-05-18 05:39:21

标签: rx-java

我在下面尝试过。

public static void main(String[] args) throws Exception {
  Observable.interval(100L, TimeUnit.MILLISECONDS)
    .onBackpressureDrop().subscribe(new Subscriber<Long>() {

    @Override
    public void onStart() {
      request(1L);
    }

    @Override
    public void onNext(Long t) {
      System.out.println("received: " + t);
      try {
        Thread.sleep(1000L);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      request(1);
    }

    @Override
    public void onCompleted() {
      System.out.println("onCompleted");
    }

    @Override
    public void onError(Throwable e) {
      e.printStackTrace();
    }
  });

  TimeUnit.SECONDS.sleep(10L);
}

我预计订阅者会收到项0, 10, 20, 30...,因为onBackpressureDrop方法会在请求之前删除项目。 但结果是0, 1, 2, 3...

此外,我尝试了onBackpressureLatest(),但结果是相同的,0, 1, 2, 3...

这在我看来与onBackpressureBuffer相同。

我是否误解了这种方法? 如果是这样,我如何尝试使用onBackpressureDrop方法作为Javadoc中的大理石图?

2 个答案:

答案 0 :(得分:2)

发生这种情况是因为你把一个()间隔()运行的线程放到了睡眠状态。一种可能的解决方案 - 添加observeOn(Scheduler,bufferSize)运算符:

  Observable.interval(100L, TimeUnit.MILLISECONDS)
            .onBackpressureDrop()
            .observeOn(Schedulers.io(), 1)
            .subscribe(new Subscriber<Long>() {

                @Override
                public void onStart() {
                    request(1L);
                }

                @Override
                public void onNext(Long t) {
                    System.out.println("received: " + t);
                    try {
                        Thread.sleep(1000L);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    request(1);
                }

                @Override
                public void onCompleted() {
                    System.out.println("onCompleted");
                }

                @Override
                public void onError(Throwable e) {
                    e.printStackTrace();
                }
            });

    Observable.empty().delay(1, TimeUnit.MINUTES).toBlocking().subscribe();

通过这种方式,您的订户可以使用最小缓冲区大小的io()调度程序运行,并且背压似乎有效:

收到:0
收到:11
收到:22

答案 1 :(得分:2)

onBackpressureDrop在这里没有做任何事情,因为在这种特殊情况下没有“背压”。您在subscribe方法中执行的操作是通过Observable.interval方法在每次发射后休眠1秒来阻止创建新值的线程。因此Observable.interval每100毫秒不生成一个值,但每秒只被强制执行一次!

我建议您在observeOnonBackpressureDrop之间添加subscribe,以便生成值以及您在subscribe中执行的操作位于不同的主题上。要查看效果,请使用缓冲区大小较小的this overload(例如1)。据我所知,任何类型的调度程序都会这样做。