RxJava 2.x:serialize()不起作用

时间:2017-01-25 01:52:22

标签: rx-java2

我在下面尝试测试sereialize()

我拨打onNext 1,000,000次来计算2个不同的线程。 然后,我预计会在onComplete获得2,000,000。

然而,我无法获得预期的价值。

private static int count = 0;

private static void setCount(int value) {
  count = value;
}

private static final int TEST_LOOP = 10;

private static final int NEXT_LOOP = 1_000_000;

@Test
public void test() throws Exception {

  for (int test = 0; test < TEST_LOOP; test++) {
    Flowable.create(emitter -> {
      ExecutorService service = Executors.newCachedThreadPool();
      emitter.setCancellable(() -> service.shutdown());

      Future<Boolean> future1 = service.submit(() -> {
        for (int i = 0; i < NEXT_LOOP; i++) {
          emitter.onNext(i);
        }
        return true;
      });

      Future<Boolean> future2 = service.submit(() -> {
        for (int i = 0; i < NEXT_LOOP; i++) {
          emitter.onNext(i);
        }
        return true;
      });

      if (future1.get(1, TimeUnit.SECONDS)
          && future2.get(1, TimeUnit.SECONDS)) {
        emitter.onComplete();
      }
    }, BackpressureStrategy.BUFFER)
        .serialize()
        .cast(Integer.class)
        .subscribe(new Subscriber<Integer>() {

          private int count = 0;

          @Override
          public void onSubscribe(Subscription s) {
            s.request(Long.MAX_VALUE);
          }

          @Override
          public void onNext(Integer t) {
            count++;
          }

          @Override
          public void onError(Throwable t) {
            fail(t.getMessage());
          }

          @Override
          public void onComplete() {
            setCount(count);
          }
        });

    assertThat(count, is(NEXT_LOOP * 2));
  }
}

我想知道serialize()是否无效或我错过了serialize()的使用

我检查了SerializedSubscriber的来源。

@Override
public void onNext(T t) {
  ...
  synchronized(this){
    ...
  }
  actual.onNext(t);
  emitLoop();
}

由于actual.onNext(t);被调出了synchronized块,我想可以同时从不同的线程调用actual.onNext(t);。此外,我猜可能会在onComplete完成之前致电onNext

我使用了RxJava 2.0.4。

1 个答案:

答案 0 :(得分:1)

这不是错误,而是FlowableEmitter的{​​{3}}:

  

应该以顺序方式调用onNext,onError和onComplete方法,就像订阅者的方法一样。如果您想确保这一点,请使用misuse。其他方法是线程安全的。

FlowableEmitter.serialize()

Flowable.serialize()运算符来说,应用create为时已晚。