在什么点上是在RxJava中创建的线程

时间:2014-03-11 16:57:36

标签: multithreading rx-java

假设我在Observable上进行了一系列转换:

operation()
    .flatMap(toSomething())
    .map(toSomethingElse())
    .flatMap(toYetSomethingElse())
    .subscribeOn(Schedulers.newThread())
    .observeOn(AdroidSchedulers.mainThread())
    .subscribe(observer);

除了最后一次调用flatMap()之外,所有这些操作是否都是同步的?或者所有操作都在我告诉它订阅的主题上运行?

1 个答案:

答案 0 :(得分:1)

我通过测试想出了这一点。以下测试通过(这意味着Observable上的排放都在同一个后台线程上):

    volatile long observableThreadId;

    @Test
    public void transformedObservables_shouldRunInSameThread() {

        Observable.from(new String[]{"a", "b", "c"}) //
            .flatMap(new Func1<String, Observable<Object>>() {
                @Override public Observable<Object> call(String s) {
                    observableThreadId = Thread.currentThread().getId();
                    return Observable.from((Object) s);
                }
            }) //
            .map(new Func1<Object, String>() {
                @Override public String call(Object o) {
                    long id = Thread.currentThread().getId();
                    if (id != observableThreadId) {
                        throw new RuntimeException("Thread ID mismatch");
                    }

                    return (String) o;
                }
            }) //
            .flatMap(new Func1<String, Observable<String>>() {
                @Override public Observable<String> call(String s) {
                    long id = Thread.currentThread().getId();
                    if (id != observableThreadId) {
                        throw new RuntimeException("Thread ID mismatch");
                    }

                    return Observable.from(s);
                }
            }) //
            .subscribeOn(Schedulers.newThread()) //
            .observeOn(Schedulers.currentThread()) //
            .subscribe(new Observer<String>() {
                @Override public void onCompleted() {
                    assertThat(Thread.currentThread().getId()).isNotEqualTo(observableThreadId);
                }

                @Override public void onError(Throwable throwable) {

                }

                @Override public void onNext(String s) {

                }
            });

        System.out.println("blah");
    }

=============================== 更新:

实际上可以在Scheduler上的ReactiveX文档中找到更好的答案:

  

默认情况下,Observable和您应用的运算符链   它将完成其工作,并将在同一个线程上通知其观察员   在其上调用订阅方法。 SubscribeOn 运算符   通过指定其中的不同调度程序来更改此行为   观察应该运作。 ObserveOn 运算符指定了一个   Observable将用于发送通知的不同Scheduler   对观察员来说。

     

... SubscribeOn 运算符指定Observable将使用哪个线程   无论在运营商链中的哪个点,都要开始运营   该运算符被调用。另一方面, ObserveOn 影响了   Observable将使用 的线程,其中显示该运算符。   因此,您可以多次调用ObserveOn   在Observable运营商链中的点,以便改变   某些运营商运营的线程。

相关问题