簡體   English   中英

RXJava Observable onNext 在不同線程上發出

[英]RXJava Observable onNext emitted on different threads

如果我嘗試在不同的線程上發出 onNext,則在訂閱它時會在下一個元素上捕獲 stream。

public static Observable<Student> getStudents()
{
    return Observable.create(e -> {

          for(int i : Arrays.asList(1,2,3))
          {
              Thread t = new Thread(() -> {

                  e.onNext(new Student("anirba", i));

              });
              t.start();
          }
          e.onComplete();
    });
}

在對這個可觀察對象進行防曬時,我沒有得到任何響應,請enter code here

Observable<Student> observer = getStudents();

    observer.subscribe(i -> System.out.println(i));

您在 create 方法中創建了三個線程,每個線程都將 Student 的 object 添加到 stream。 您沒有得到任何 output 的原因是所有這三個線程將獨立運行並基於線程調度程序將被執行。 在您的情況下,可能會在所有這三個線程將數據添加到 Observable stream 之前調用 onComplete() 方法。 和 onComplete 待命時,stream 將關閉,stream 將不再接受任何數據。 為了使其僅適用於以下更改,它應該按您的預期工作。

public static Observable<Student> getStudents() {
    return Observable.create(e -> {
          for(int i : Arrays.asList(1,2,3)) {
              Thread t = new Thread(() -> {
                  e.onNext(new Student("anirba", i));
              });
              t.start();
          }
          Thread.sleep(1000);
          e.onComplete();
    });
}

java.util.concurrent.Executor是正確的 API 現在用於運行任務。 要阻塞當前線程,您可以使用CountDownLatch並在所有任務終止時釋放它。

ExecutorService executor = Executors.newCachedThreadPool(); // choose the right one

public Observable<Student> getStudents() {
    return Observable.<Student>create(emitter -> {
        List<Integer> source = Arrays.asList(1, 2, 3);
        CountDownLatch latch = new CountDownLatch(source.size());

        source
                .forEach(i ->
                        executor.submit(() -> {
                            emitter.onNext(new Student("anirba", i));
                            latch.countDown();
                        }));

        latch.await();
        emitter.onComplete();
    }).serialize();
}

在其他地方不要忘記在executor上調用shutdown()

您還可以添加serialize()運算符以避免onnext()調用重疊。

合同

Observables 必須串行(而不是並行)向觀察者發出通知。 他們可能會從不同的線程發出這些通知,但通知之間必須有正式的先發生關系。

為了進行測試,您可以添加Thread.sleep(x)來查看您的登錄信息。 我已經在這里回答過這個問題

public static void main(String[] args) throws InterruptedException {
     getStudents()
             .subscribe(i -> System.out.println(i));
    
    Thread.sleep(2000);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM