CompletableFuture
、Future
、およびObservable
RxJava
の違いを知りたいのですが。
私が知っているのはすべて非同期だが
Future.get()
はスレッドをブロックします
CompletableFuture
はコールバックメソッドを与えます
RxJava Observable
--- CompletableFuture
と似ていますが、その他の利点があります(確実ではありません)。
たとえば、クライアントが複数のサービス呼び出しを行う必要があり、Futures
(Java)を使用する場合はFuture.get()
が順次実行されます。
そしてドキュメンテーション http://reactivex.io/intro.html は言う
Futuresを使用して条件付き非同期実行フローを最適に構成することは困難です(または各要求の待ち時間が実行時に異なるため不可能です)。もちろんこれは可能ですが、すぐに複雑になり(したがってエラーが発生しやすく)、またはFuture.get()で時期尚早にブロックされ、非同期実行の利点がなくなります
RxJava
がこの問題をどのように解決するかを知りたいと本当に興味があります。文書から理解するのは難しいと思いました。
先物
Futures はJava 5(2004)で導入されました。彼らは基本的にまだ起こっていない結果のプレースホルダーです。彼らはその操作が完了したら、ある操作の結果を保持することを約束します。この操作は、 Runnable または Callable インスタンスに送信され、 ExecutorService に送信されます。操作の実行依頼者は、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 、 Guava ライブラリーの一部に触発された通常の先物の進化です。彼らはまた、あなたがチェーンで一緒にタスクをつなぐことを可能にする先物です。それらを使用して、ワーカースレッドに「タスクXを実行し、完了したら、Xの結果を使用してこれ以外のことを実行する」ように指示できます。これは簡単な例です:
/**
* 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を使用して、一連の同期または非同期アクションをまとめて処理パイプラインを作成できます。使い捨ての先物とは異なり、RxJavaは0個以上のアイテムのストリームで動作します。無限の数のアイテムを持つ終わりのないストリームを含みます。信じられないほど豊富な 演算子のセット のおかげで、はるかに柔軟で強力です。
Java 8のストリームとは異なり、RxJavaには バックプレッシャ メカニズムもあります。これにより、処理パイプラインの異なる部分が異なるスレッドで動作する場合を異なるレートで処理できます。 ).
RxJavaの欠点は、しっかりしたドキュメントにもかかわらず、パラダイムシフトがあるために学ぶのが難しいライブラリだということです。 Rxコードは、特に複数のスレッドが関与している場合、そしてさらに悪いことに - バックプレッシャーが必要な場合には、デバッグするのに悪夢となる可能性もあります。
あなたがそれに参加したいのであれば、公式のWebサイト上のさまざまなチュートリアルの全体 ページ に加えて、公式の ドキュメント と Javadoc があります。 this one のようないくつかのビデオを見てみることもできます。これはRxの簡単な紹介で、RxとFuturesの違いについても述べています。
おまけ:Java 9 Reactive Streams
Java 9のReactive Streams aka Flow API は、 RxJava 2 のようなさまざまな Reactive Stream ライブラリによって実装されるインタフェースのセットです。 、 Akka Streams 、および Vertx 。これらは、すべての重要なバックプレッシャーを維持しながら、これらのリアクティブライブラリを相互接続することを可能にします。
私は0.9からRx Javaで働いていて、今は1.3.2で、すぐに2.xに移行しています。私はこれを私が既に8年間取り組んでいる私的プロジェクトで使います。
私はもうこのライブラリなしではプログラムしないでしょう。初めは私は懐疑的でしたが、それはあなたが創造する必要がある完全な他の心の状態です。初めは静かにしてください。私は時々ビー玉を何時間も見ていました..笑
それは単なる実務上の問題であり、実際にその流れ(オブザーバブルとオブザーバの契約)を知ることです。
私にとって、そのライブラリには本当にマイナス面はありません。
ユースケース:9つのゲージ(cpu、mem、networkなど)を含むモニタービューがあります。ビューを起動すると、ビューは9メートルのすべてのデータを含む観測可能値(間隔)を返すシステムモニタクラスに加入します。それは毎秒ビューに新しい結果をプッシュします(だからポーリングしません!!!)。このオブザーバブルはフラットマップを使用して9つの異なるソースからデータを同時に(非同期で)フェッチし、その結果をビューがonNext()で取得する新しいモデルに圧縮します。
どのようにしてあなたが未来や補完物などを使ってそれをやろうとしているのでしょう...頑張ってください! :)
Rx Javaは私のためにプログラミングの多くの問題を解決し、ある意味でずっと簡単になります...
利点:
デメリット: - テストが難しい