2016-11-08 1 views
7

どのスレッドがunsubscribeOnであるのですか?指定されていないにもかかわらず、subscribeOnのスレッドはまだ指定されていない場合はデフォルトになっていますか? subscribeOnで使用されているものと同じスレッドであっても、サブスクリプションを解除するスレッドを指定する必要がありますか?unSubscribeOnとはどのスレッドが呼び出されていますか?私たちはそれを呼びますか?

また、アンサブスクリプションで同じ2つのスニペットが実行されていますか?

オプション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を見てなかったけど、彼らは唯一の(observeOnなしと)subscribeOnなければunSubscribeOn

答えて

3

についてsubscribeOnが、何も説明サブスクリプションが開始されたどのスレッドでもサブスクリプション解除アクションが発生します。

subscribeOnの場合、subscribeOnで指定されたスケジューラで登録解除処理が行われます。

observeOnでは、observeOnsubscribeOnで指定されたスケジューラーを上書き)で指定されたスケジューラーで、サブスクライブ解除アクションが発生します。

ここにはsampleがあります。そこに示唆されているように、アンサブスクリプション自体に、他のスレッドで実行したい長期実行の操作が含まれている場合に便利です。

あなたはそれらのテストコードを実行した場合:あなたはそのunsubscribeOn行を削除する場合は、あなたが表示されます

Subscribed on 1 
Producing on 1 
1 
2 
Unubscribed on 11 

Unsubscribed on 1 
+0

お返事ありがとうございます。私はunSubscribeOnが起こっているスレッドの説明が好きです。しかし、このサンプルは私がテスト用に作成したサンプルで示したようには機能しません。私にとっては、同じスレッドでも購読解除が行われています。 '1'。私はそれを受け入れることができるようにあなたのコードを修正したいですか?もう1つは、あなたが言及した 'ドキュメント'は実際にはサンプルであるということです。実際のRx-Javaドキュメントではありません。実際のドキュメントはhttp://reactivex.io/intro.htmlです。 – achie

+0

ああ、良いキャッチ - うん、確かに実際のドキュメントではない。スレッドをチェックするために使用している完全なコードを投稿できますか? – drhr

+0

ええ、私はあなたの答えを更新するために使用することができるように別の答えとして追加します。私のアプローチで何か間違いをしている場合は、それを修正するかもしれません:) – achie

3

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); 

をあなたが彼らの予想される出力が表示されるはずです

これらのスニペットの動作は異なります。

通常、サブスクリプションはオペレータシーケンスを移動し、どのスレッドからでも開始できます(任意のスレッドからsubscriber.unsubscribe()を呼び出してください)。 unsubscribeOnオペレータが存在しなければ、unsubscribeアクションは、おそらくそれが呼び出されたスレッドでアクションを完了します。 unsubscribeOnは、その上流の購読解除に使用されるスレッドをより細かく制御します。

1

どのスレッドがunsubscribeOnで指定されていない場合は、デフォルトでは ですが、まだsubscribeOnのスレッドを指定していますか?デフォルトで

  • subscribeOn/observeOn/unsubscribeOnのいずれもその後 セット、unsubscribeOn(ならびに他の)である 現在のスレッドにデフォルト設定されています。我々は observeOn/unsubscribeOnためsubscribeOnのためのスレッドとなしを設定しない場合

  • 、そしてunsubscribeOnはsubscribeOnで指定された同じスレッド を使用します。

  • subscribeOnとObserveOnの両方を呼び出しますが、unsubscribeOnは呼び出さない場合、 unsubscribeOnはobserveOnで指定されたスレッドを使用します。すべての3つの方法(subscribeOn、observeOn及びunsubscribeOn)が 設定されている場合

  • は、その後unsubscribeOnは unsubscribeOnで指定されたスレッドを使用します。事実、unsubscribeOnは、以前の メソッドが設定されているかどうかに関係なく、unsubscribeOnメソッドで指定されたスレッド で発生します。

我々はそれが subscribeOnで使用されるものと同じスレッドであっても、上で起こる、我々は に未加入したいスレッドを指定する必要がありますか?

  • としては、それが設定されている場合 はobserveOnで発生unsubscribeOn unsubscribeOnが設定されていない場合は、上記説明しました。そうでなければ、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します。それは私が上記のサンプルでより多くを研究し、結果を検証するのに役立ちました。

+0

それはすべて正しく見える。あなたの結果は何が違うのですか? – drhr

+0

ああ、私が持っていた問題は、UnSubscribeOnで指定されたスレッドでUnubscribed onというクレームにリンクしたサンプルに表示されている例が、私のために働くことができなかったということでした。その代わりに、subscribeOnが使用するスレッド上で発生しました。私はあなたのサンプルでこれを演奏しました。 (サブスクライバー)。それはサブスクリプションとアンサブスクリプションが同じスレッド 'Unbscribed on 564 RxIoScheduler-3' – achie

+0

で起こったと私はsubscribeOnを呼び出さずに、単にunsubscribeOnにスレッドを指定しても、新しいスレッドを使用していない。代わりに、すべて同じスレッドから起こっていた。あなたの答えのスレッドIDとして11ではなく1を返します。 – achie

関連する問題