简体   繁体   English

RXJava Observable onNext 在不同线程上发出

[英]RXJava Observable onNext emitted on different threads

If i try to emit onNext on different thread's, on subscribing it dosent catch the stream on next elements.如果我尝试在不同的线程上发出 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();
    });
}

On sunbscribing to this observable i dont get any response enter code here在对这个可观察对象进行防晒时,我没有得到任何响应,请enter code here

Observable<Student> observer = getStudents();

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

You are creating three threads inside the create method and each is adding an object of Student to stream.您在 create 方法中创建了三个线程,每个线程都将 Student 的 object 添加到 stream。 The reason why you are not getting any output is all these three threads will be running independently and based on thread scheduler it will be executed.您没有得到任何 output 的原因是所有这三个线程将独立运行并基于线程调度程序将被执行。 In your case, the onComplete() method might get called before all these three threads add data into the Observable stream.在您的情况下,可能会在所有这三个线程将数据添加到 Observable stream 之前调用 onComplete() 方法。 and on-call of onComplete, the stream will be closed and no more data will be accepted by the stream.和 onComplete 待命时,stream 将关闭,stream 将不再接受任何数据。 To make it work just to the below changes, it should work as you are expecting.为了使其仅适用于以下更改,它应该按您的预期工作。

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 is the right API now for running tasks. java.util.concurrent.Executor是正确的 API 现在用于运行任务。 To block the current thread you can use CountDownLatch and release it when all tasks are terminated.要阻塞当前线程,您可以使用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();
}

And elsewhere don't forget to call shutdown() on the executor .在其他地方不要忘记在executor上调用shutdown()

You may also add serialize() operator to avoid onnext() calls to overlap.您还可以添加serialize()运算符以避免onnext()调用重叠。

From the contract :合同

Observables must issue notifications to observers serially (not in parallel). Observables 必须串行(而不是并行)向观察者发出通知。 They may issue these notifications from different threads, but there must be a formal happens-before relationship between the notifications.他们可能会从不同的线程发出这些通知,但通知之间必须有正式的先发生关系。

For the perpose of testing you can add Thread.sleep(x) to see your loggin.为了进行测试,您可以添加Thread.sleep(x)来查看您的登录信息。 I've already answerd this before here我已经在这里回答过这个问题

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