unSubscribeOn调用了什么线程?我们应该打电话吗?

时间:2016-11-08 21:17:17

标签: java android rx-java rx-android

当我们没有指定它但仍指定subscribeOn的线程时,unsubscribeOn默认为什么线程? 我们是否需要指定我们想要取消订阅的线程,即使它与subscribeOn中使用的线程相同?

或者底部的两个片段是否为取消订阅做同样的事情?

选项1:

mSubscription.add(myAppProvider
        .getSomeData()
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .unsubscribeOn(Schedulers.io())
        .subscribe(data -> handleData(data),
                throwable -> handleError(throwable)
                ));

选项2:

mSubscription.add(myAppProvider
        .getSomeData()
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(data -> handleData(data),
                throwable -> handleError(throwable)
                ));

我确实看过Rx-Java docs,但他们只解释了subscribeOn,但没有解释unSubscribeOn

3 个答案:

答案 0 :(得分:4)

如果没有downState(并且没有upState),您的取消订阅操作将在订阅开始的任何线程上发生。

使用subscribeOn,您的取消订阅操作将在observeOn指定的计划程序上进行。

使用subscribeOn,您的取消订阅操作将在subscribeOn指定的计划程序上进行(覆盖observeOn指定的计划程序)。

这是sample。正如那里所建议的那样,当unsubscription本身涉及你想在其他线程上运行的长时间运行时,这很有用。

如果你运行他们的测试代码:

observeOn

你应该看到他们的预期输出:

subscribeOn

如果删除Observable<Object> source = Observable.using( () -> { System.out.println("Subscribed on " + Thread.currentThread().getId()); return Arrays.asList(1,2); }, (ints) -> { System.out.println("Producing on " + Thread.currentThread().getId()); return Observable.from(ints); }, (ints) -> { System.out.println("Unubscribed on " + Thread.currentThread().getId()); } ); source .unsubscribeOn(Schedulers.newThread()) .subscribe(System.out::println); 行,您会看到:

 Subscribed on 1
 Producing on 1
 1
 2
 Unubscribed on 11

答案 1 :(得分:3)

这些片段有不同的行为。

通常,取消订阅会沿着运算符序列运行,并且可以由任何线程启动(只需从任何线程调用subscriber.unsubscribe())。如果没有unsubscribeOn运算符,则取消订阅操作可能会在调用它的线程上完成其操作。 unsubscribeOn可以更好地控制用于上游取消订阅的线程。

答案 2 :(得分:1)

  

什么线程是unsubscribeOn默认为我们没有指定它   但是仍然为subscribeOn指定线程?

  • 默认情况下,subscribeOn / observeOn / unsubscribeOn都不是 设置,然后unsubscribeOn(以及其他人)默认为 当前主题。

  • 如果我们为subscribeOn设置了一个线程而没有为 observeOn / unsubscribeOn,然后unsubscribeOn将使用相同的线程 在subscribeOn中指定。

  • 如果我们同时调用subscribeOn和ObserveOn但不调用unsubscribeOn,那么 unsubscribeOn将使用observeOn中指定的线程。

  • 如果所有三种方法(subscribeOn,observeOn和unsubscribeOn)都是 设置,然后unsubscribeOn将使用指定的线程 unsubscribeOn。实际上unsubscribeOn会在线程上发生 在unsubscribeOn方法中指定,无论以前的天气如何 方法是否设定。

  

我们是否需要指定要取消订阅的线程   即使它与使用的线程相同,也会发生   subscribeOn?

  • 如上所述,如果未设置unsubscribeOn,则取消订阅 如果已设置,则发生在observeOn上。如果没有那么它就发生了 由subscribeOn设置的线程。现在我们不需要设置不同的 除非你正在做一些长时间运行的任务,否则unsubscribeOn的线程 取消订阅。在大多数情况下或至少来自我的代码,这是 是的,所以我们不必设置不同的线程。

以下是我创建的一个示例,可用于在Android中测试上述内容。只需注释或更改线程,以测试各种结果。

    public void testRxThreads() {
        createThreadObservable()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .unsubscribeOn(Schedulers.newThread())
            .subscribe(printResult());
    }

    private Observable<String> createThreadObservable() {
        return Observable.create(subscriber -> {
            subscriber.add(new Subscription() {
                @Override
                public void unsubscribe() {
                    System.out.println("UnSubscribe on Thread: "
                        + Thread.currentThread().getId() + " " + Thread.currentThread().getName());
                    // perform unsubscription
                }

                @Override
                public boolean isUnsubscribed() {
                    return false;
                }
            });

            subscriber.setProducer(n -> {
                System.out.println("Producer thread: "
                    + Thread.currentThread().getId() + " " + Thread.currentThread().getName());
            });

            subscriber.onNext("Item 1");
            subscriber.onNext("Item 2");
            subscriber.onCompleted();
        });
    }

    private Action1<String> printResult() {
        return result -> {
            System.out.println("Subscriber thread: "
                + Thread.currentThread().getId() + " " + Thread.currentThread().getName());
            System.out.println("Result: " + result);
        };
    }

这产生了以下结果

Producer thread: 556 RxIoScheduler-2
Subscriber thread: 1 main
Result: Item 1
Subscriber thread: 1 main
Result: Item 2
UnSubscribe on Thread: 557 RxNewThreadScheduler-1

注释掉或删除unsubscribeOn会产生以下结果。

Subscriber thread: 1 main
Result: Item 1
Subscriber thread: 1 main
Result: Item 2
UnSubscribe on Thread: 1 main

删除observeOn和unsubscribeOn调用会产生以下结果:

Producer thread: 563 RxIoScheduler-2
Subscriber thread: 563 RxIoScheduler-2
Result: Item 1
Subscriber thread: 563 RxIoScheduler-2
Result: Item 2
UnSubscribe on Thread: 563 RxIoScheduler-2

感谢drhr对事件的初步解释。这帮助我更多地研究并用上面的样本验证结果。