CompletableFuture、Future、RxJavaのObservableの違い


193

私はとの違いを知りたいのですが CompletableFutureFutureObservable RxJava

私が知っていることはすべて非同期ですが

Future.get() スレッドをブロックします

CompletableFuture コールバックメソッドを提供します

RxJava Observable--- CompletableFuture他の利点と同様(不明)

たとえば、クライアントが複数のサービス呼び出しを行う必要があり、Futures(Java)を使用する場合、Future.get()順次実行されます... RxJavaでそれがどのように優れているかを知りたいです。

そして、ドキュメントhttp://reactivex.io/intro.htmlは言う

Futuresを使用して条件付き非同期実行フローを最適に構成することは困難です(または各リクエストのレイテンシは実行時に変化するため不可能です)。もちろん、これは可能ですが、すぐに複雑になり(エラーが発生しやすくなる)、Future.get()で途中でブロックされ、非同期実行の利点がなくなります。

RxJavaこの問題をどのように解決するかを知りたいと本当に思っています。ドキュメントから理解するのは難しいと思いました。


それぞれのドキュメントを読みましたか?私はRxJavaに完全に不慣れですが、ドキュメントは一目で非常に完全に表示されます。2つの先物に特に匹敵するようには見えません。
FThompson 2016

私は経験しましたが、Java先物との違いを得ることができません...もし間違っていれば訂正してください
shiv455

オブザーバブルは先物とどのように似ていますか?
FThompson 2016

2
スレッド管理が異なるように、それがどこで違うのか知りたいですか?EX:Future.get()はスレッドをブロックします...それはObservableでどのように処理されますか???
shiv455

2
少なくとも私には少し混乱しています...高いレベルの違いは本当に役に立ちます!
shiv455

回答:


278

先物

先物はJava 5(2004)で導入されました。これらは基本的に、まだ完了していない操作の結果のプレースホルダーです。操作が完了するFutureと、にその結果が含まれます。たとえば、操作は、ExecutorServiceに送信されるRunnableまたはCallableインスタンスにすることができます。。操作の送信者は、Futureオブジェクトを使用して、操作がisDone()であるかどうかを確認するか、ブロッキングget()メソッドを使用して操作が完了するのを待ちます。

例:

/**
* A task that sleeps for a second, then returns 1
**/
public static class MyCallable implements Callable<Integer> {

    @Override
    public Integer call() throws Exception {
        Thread.sleep(1000);
        return 1;
    }

}

public static void main(String[] args) throws Exception{
    ExecutorService exec = Executors.newSingleThreadExecutor();
    Future<Integer> f = exec.submit(new MyCallable());

    System.out.println(f.isDone()); //False

    System.out.println(f.get()); //Waits until the task is done, then prints 1
}

CompletableFutures

CompletableFuturesはJava 8(2014)で導入されました。これらは実際、グアバの一部であるGoogleのListenable Futuresに触発された通常のFuturesの進化形です。ライブラリのます。これらはFutureであり、タスクをチェーンでつなぐこともできます。それらを使用して、「いくつかのタスクXを実行し、完了したらXの結果を使用して別のことを行う」ようにいくつかのワーカースレッドに指示できます。CompletableFuturesを使用すると、実際にスレッドをブロックして結果を待つことなく、操作の結果を処理できます。以下に簡単な例を示します。

/**
* A supplier that sleeps for a second, and then returns one
**/
public static class MySupplier implements Supplier<Integer> {

    @Override
    public Integer get() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            //Do nothing
        }
        return 1;
    }
}

/**
* A (pure) function that adds one to a given Integer
**/
public static class PlusOne implements Function<Integer, Integer> {

    @Override
    public Integer apply(Integer x) {
        return x + 1;
    }
}

public static void main(String[] args) throws Exception {
    ExecutorService exec = Executors.newSingleThreadExecutor();
    CompletableFuture<Integer> f = CompletableFuture.supplyAsync(new MySupplier(), exec);
    System.out.println(f.isDone()); // False
    CompletableFuture<Integer> f2 = f.thenApply(new PlusOne());
    System.out.println(f2.get()); // Waits until the "calculation" is done, then prints 2
}

RxJava

RxJavaリアクティブプログラミング用のライブラリ全体です、Netflixで作成されたです。一見すると、Java 8のストリームに似ているように見えます。それは、それがはるかに強力であることを除いてです。

Futuresと同様に、RxJavaを使用して、一連の同期アクションまたは非同期アクションをつなぎ合わせて、処理パイプラインを作成できます。使い捨てのFutureとは異なり、RxJava は0個以上のアイテムのストリームで機能します。無限の数のアイテムで終わることのないストリームを含みます。また、信じられないほど豊富なおかげで、はるかに柔軟で強力です演算子のセットのです。

Java 8のストリームとは異なり、RxJavaにはバックプレッシャーメカニズムもあり、処理パイプラインのさまざまな部分がさまざまなスレッドで動作するケースを処理できます。でさまざまなレートでます

RxJavaの欠点は、ドキュメントがしっかりしているにもかかわらず、パラダイムシフトが関係しているため、学ぶのが難しいライブラリであることです。特に複数のスレッドが関係している場合、Rxコードはデバッグの悪夢にもなり得ます。

知りたい場合は、公式Webサイトにさまざまなチュートリアルの全ページに加えて、公式ドキュメントJavadocがあります。また、次のようなビデオのいくつかを見ることができます Rxの簡単な紹介と、RxとFuturesの違いについて説明しこのます。

ボーナス:Java 9 Reactive Streams

Java 9のReactive Streams別名Flow APIは、RxJava 2Akka StreamsVertxなどのさまざまなリアクティブストリームライブラリによって実装される一連のインターフェースです。それらは、すべての重要なバックプレッシャーを維持しながら、これらの反応ライブラリーが相互接続することを可能にします。


Rxがこれを行う方法のコード例を示すとよいでしょう
Zinan Xing

では、Reactive Streamsを使用すると、RxJava、Akka、Vertxを1つのアプリケーションに混在させることができますか?
IgorGanapolsky 2017年

1
@IgorGanapolskyはい。
モルト

CompletableFuturesではコールバックメソッドを使用します。これらのコールバックメソッドは、1つのメソッドの出力が他のコールバックの入力である場合もブロックします。Future.get()呼び出しを含むfutureブロックとして。CompletableFuturesがブロックしないのに、Future.get()が呼び出しをブロックしていると言われている理由。説明してください
ディーパック

1
@フェデリコ確かに。それぞれFutureが、まだ完了していない可能性がある単一の結果のプレースホルダーです。同じ操作をもう一度実行すると、新しいFutureインスタンスが取得されます。RxJavaは、いつでも発生する可能性がある結果のストリームを処理します。したがって、一連の操作は、一連の結果を送り出す単一のRxJavaオブザーバブルを返すことができます。それは、単一の郵便封筒と郵便物を送り出し続ける気送管の違いに少し似ています。
モルト

20

私は0.9からRx Javaを使用しており、現在は1.3.2で、すぐに2.xに移行しています。これをプライベートプロジェクトで使用し、すでに8年間取り組んでいます。

このライブラリがないと、もうプログラムはできません。最初は私は懐疑的でしたが、それはあなたが作成する必要がある完全に他の心の状態です。最初は難しい静かな。私は時々ビー玉を見ていました。

それは単なる練習の問題であり、実際にフロー(別名オブザーバブルとオブザーバーの契約)を理解することです。いったんそこに着くと、それ以外の方法でそれを行うのは嫌になります。

私にとって、そのライブラリには実際にマイナス面はありません。

使用例:9つのゲージ(cpu、mem、ネットワークなど)を含むモニタービューがあります。ビューを開始すると、ビューは、9メートルのすべてのデータを含むオブザーバブル(間隔)を返すシステムモニタークラスにサブスクライブします。毎秒新しい結果がビューにプッシュされます(ポーリングしない!!!)。そのオブザーバブルはフラットマップを使用して同時に9つの異なるソースからデータをフェッチし(非同期!)、結果をonNext()でビューが取得する新しいモデルに圧縮します。

先物、完了品などでこれをどうするつもりなの...頑張ってください!:)

Rx Javaは私にとってプログラミングの多くの問題を解決し、ある意味ではるかに簡単にします...

利点:

  • Statelss !!! (言及すべき重要なこと、おそらく最も重要なこと)
  • すぐに使えるスレッド管理
  • 独自のライフサイクルを持つシーケンスを構築する
  • すべてが観測可能なので、連鎖は簡単です
  • 書くコードが少ない
  • クラスパス上の単一のjar(非常に軽量)
  • 高度な同時性
  • コールバック地獄はもうありません
  • 加入者ベース(消費者と生産者間の緊密な契約)
  • バックプレッシャー戦略(サーキットブレーカーなど)
  • 素晴らしいエラー処理と回復
  • とても素敵なドキュメント(大理石<3)
  • 完全な制御
  • もっともっと...

短所:-テストが難しい


13
〜「このライブラリなしでプログラムすることはもうありません。」それで、RxJavaはすべてのソフトウェアプロジェクトにとって結局のところすべてでしょうか。
IgorGanapolsky 2017年

Stream of Asynchronousイベントがなくても役に立ちますか?
Mukesh Verma
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.