観察可能なvs流動可能なrxJava2


127

私は新しいrx java 2を見ていました、そして私がbackpressureもうの考えを理解しているのかよくわかりません...

私たちにObservablebackpressureサポートがなく、サポートがあることは知っFlowableています。

例に基づいて、私が持っているflowableとしましょうinterval

        Flowable.interval(1, TimeUnit.MILLISECONDS, Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Consumer<Long>() {
                @Override
                public void accept(Long aLong) throws Exception {
                    // do smth
                }
            });

これは約128個の値の後でクラッシュします。これは、アイテムを取得するよりも消費が遅いことは明らかです。

しかし、私たちは同じです Observable

     Observable.interval(1, TimeUnit.MILLISECONDS, Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Consumer<Long>() {
                @Override
                public void accept(Long aLong) throws Exception {
                    // do smth
                }
            });

消費を遅らせても、これはまったく機能しません。Flowable仕事をするためにonBackpressureDrop、私が演算子を置くとしましょう、クラッシュはなくなりましたが、すべての値が放出されるわけではありません。

だから私が現在頭の中で答えを見つけることができない基本的な質問はなぜbackpressure私がプレーンを使用できるのか気にすべきなObservablebufferですか?それとも反対側からbackpressure、消費の管理と処理に有利な点は何ですか?


回答:


122

Flowable.observeOnバックプレッシャーが実際に示すのは境界付きバッファーであり、128要素のバッファーがあり、ダウンストリームが処理できる速度で排出されます。バースト性のあるソースを処理するためにこのバッファサイズを個別に増やすことができ、すべてのバックプレッシャー管理プラクティスは1.xから引き続き適用されます。Observable.observeOn要素を収集し続ける無制限のバッファがあり、アプリがメモリ不足になる可能性があります。

Observableたとえば、次のように使用できます。

  • GUIイベントの処理
  • 短いシーケンスでの作業(合計1000要素未満)

Flowableたとえば、次のように使用できます。

  • コールドで非タイミングのソース
  • ソースのようなジェネレータ
  • ネットワークおよびデータベースアクセサー

これは来ているので、別の質問に -それはのようなものより制限されたタイプを修正しているMaybeSingleCompletableすることができ、常に代わりに使用されFlowable、彼らは意味的に適切であるとき?
david.mihola 2017年

1
はい、MaybeSingle、とCompletableしているはるかに背圧の概念の必要性を持っているには小さすぎます。0〜1個のアイテムが生成または消費されるため、プロデューサーが消費するよりも速くアイテムを放出できる可能性はありません。
AndrewF

多分私は正しくないかもしれませんが、私にとってはFlowableとObservableの例を交換する必要があります。
Yura Galavay

私は、彼がFlowableに提供する必要があるバックプレッシャー戦略を欠いているという質問で、欠落しているバックプレッシャー例外がスローされる理由を説明し、.onBackpressureDrop()を適用した後にこの例外が消える理由も説明していると思います。また、Observableの場合、この戦略がなく、提供できないため、OOMのために後で失敗するだけです
Haomin

110

バックプレッシャーは、オブザーバブル(パブリッシャー)がサブスクライバーが処理できるよりも多くのイベントを作成している場合です。したがって、サブスクライバーにイベントが欠落している場合や、最終的にメモリ不足につながる大量のイベントキューを取得する場合があります。 Flowable背圧を考慮に入れます。 Observableではない。それでおしまい。

じょうごを思い出し、液体が多すぎるとオーバーフローします。Flowableはそれを起こさないようにするのに役立ちます:

途方もない背圧で:

ここに画像の説明を入力してください

しかし、flowableを使用すると、背圧がはるかに少なくなります。

ここに画像の説明を入力してください

Rxjava2には、ユースケースに応じて使用できるいくつかのバックプレッシャー戦略があります。戦略とは、Rxjava2がオーバーフロー(バックプレッシャー)のために処理できないオブジェクトを処理する方法を提供することを意味します。

ここに戦略があります。 私はそれらすべてについては説明しませんが、たとえば、オーバーフローしたアイテムについて心配したくない場合は、次のようなドロップ戦略を使用できます。

observable.toFlowable(BackpressureStrategy.DROP)

私の知る限りでは、キューに128アイテムの制限があるはずです。その後、オーバーフロー(バックプレッシャー)が発生する可能性があります。128でなくても、その数に近いです。これが誰かを助けることを願っています。

バッファサイズを128から変更する必要がある場合は、次のように実行できます(ただし、メモリの制約に注意してください:

myObservable.toFlowable(BackpressureStrategy.MISSING).buffer(256); //but using MISSING might be slower.  

ソフトウェア開発では、通常、バックプレッシャ戦略は、コンシューマが放出イベントの速度を処理できないため、エミッタを少し遅くするように指示することを意味します。


私はいつも、
バックプレッシャーは

ケースかもしれません。はい
j2emanue

Flowableを使用することの欠点はありますか?
IgorGanapolsky

これらの画像は私に嘘をついています。イベントをドロップしても、下部に「より多くのお金」が発生することはありません。
EpicPandaForce

1
@ j2emanue、演算子とFlowable.buffer(int)演算子のバッファーサイズを混同しています。javadocsをよく読んで回答を適宜修正してください。activex.io/ RxJava / 2.x / javadoc / io / reactivex
Flowable.html

15

Flowableバックプレッシャー処理なしで128の値を出力した後にクラッシュしたという事実は、正確に128の値の後で常にクラッシュすることを意味しません。10の後でクラッシュすることもあれば、まったくクラッシュしないこともあります。これは、例を試したときに起こったことだと思います。Observableたまたまバックプレッシャーがないため、コードは正常に機能しましたが、次回は機能しない可能性があります。RxJava 2の違いは、sにバックプレッシャーの概念がObservableなく、それを処理する方法がないことです。おそらく明示的なバックプレッシャー処理を必要とする反応シーケンスを設計している場合Flowableは、それが最良の選択です。


はい私は時々それがより少ない値の後で壊れた、時にはそれがそうでなかったことを観察しました。しかし、たとえば、もし私がそれintervalなしでのみ処理している場合、backpressure奇妙な動作や問題を予期するでしょうか?
user2141889

特定のObservableシーケンスでバックプレッシャーの問題が発生する可能性がないことを確信している場合は、バックプレッシャーを無視しても問題ないと思います。
Egor 2016年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.