3

私はいくつかのコードを継承しましたし、元の開発者が左の誰もありません。コードは大きくCompletableFutureを使用しています。初めて使用するので、まだ私の頭の中を包み込んでいます。私が理解しているように、通常はが、時間のかかる作業が実行されている間に何か他のことを行うことを可能にするマルチスレッド化メカニズムとともに使用され、その後単にFutureを介してその結果をフェッチします。しかし、私は継承しました。このアプリケーションでは、任意のマルチスレッドを使用していない次のパターンは時代の束現れるマルチスレッドを使用せずにFutureを使用するポイントは何ですか?

interface ArchiveSearcher { String search(String target); } 
class App { 
    ExecutorService executor = ... 
    ArchiveSearcher searcher = ... 
    void showSearch(final String target) throws InterruptedException { 
     Future<String> future = executor.submit(new Callable<String>() { 
     public String call() { 
      return searcher.search(target); 
     }}); 
     displayOtherThings(); // do other things while searching 
     try { 
      displayText(future.get()); // use future 
     } catch (ExecutionException ex) { cleanup(); return; } 
    } 
} 

the javadocのように私には

public Object serve(Object input) throws ExecutionException, InterruptedException { 
    CompletableFuture<Object> result = delegate1(input); 
    return result.get(); 
} 

private CompletableFuture<Object> delegate1(Object input) { 
    // Do things 
    return delegate2(input); 
} 

private CompletableFuture<Object> delegate2(Object input) { 
    return CompletableFuture.completedFuture(new Object()); 
} 

を、これはあります相当:もちろん

public Object serve(Object input) { 
    Object result = delegate1(input); 
    return result; 
} 

private Object delegate1(Object input) { 
    // Do things 
    return delegate2(input); 
} 

private Object delegate2(Object input) { 
    return new Object(); 
} 

コードははるかに複雑で、エラーの場合にはexceptionallyCompletedFutureを返しますが、Callableである、ないRunnable、no Executor、no supplyAsync()マルチスレッドの兆候はありません。私は何が欠けていますか?単一スレッドのコンテキストでFutureを使用するポイントは何ですか?

+0

UI関連の作業はありますか?メインスレッドが物を計算する場合、多くは遅くなります。 –

+0

@ChristianKuetbachいいえ、ありません。しかし、もしあればどうしますか? 「メインスレッド」はどういう意味ですか?私のポイントは、上記のアプローチで私の理解には、すべての "メインスレッド"です。 – mark951131b

+0

私はAndroidの開発者ではありませんが、私は主なスレッドとは何かを意味するようなAndroidの質問をたくさん見てきました。 SwingのEvent Dispatch Threadのようなものです。 –

答えて

0

ExecutorServiceの実装は、通常のスレッドを管理します。私はThreadPoolExecutorを使用しました。これはまさにそのことです。コードで使用するExecutorServiceをコメントアウトしました。

+3

'ExecutorService'を使用するコードスニペットは反例です - OP_does_が理解できるものの例です。実際の質問は、2番目のスニペットで 'CompletableFuture.completedFuture(...)'を呼び出すことです。 –

+0

@ jameslargeまさに、ありがとう。 – mark951131b

1

はい、今のところそのコードで使われたマルチスレッドがありません。もし開発者が、後にのみ

delegate2() 

方法を変更する必要があり、その後マルチスレッディングを使用することを決定するようにシングルスレッドコードを記述する意図があったように見えます。

2

先物は非同期プログラミングがある状況のために重要です。非同期プログラミングの最大の利点の1つは、単一スレッドで非常に効率的なコードを書くことができることです。

さらに、先物はオール・オア・ナッシングの命題になる傾向があります。非同期コードを記述したい場合は、すべてのメソッドが非同期を行うわけではないにもかかわらず、上から順にコードを実行する必要があります。

例えば、twistedまたはexpressのような単一スレッドのHTTPサーバーを作成するとします。

while (true) { 
    if (serverSocket.ready()) { 
    connection = serverSocket.accept(); 
    futures.add(server.serve(connection)); 
    } 
    for (Future future : futures) { 
    if (future.isDone()) { 
     Object result = future.get(); 
     sendResult(result); 
    } 
    } 
    //Some kind of select-style wait here 
} 

が一つだけのスレッドがありますが、いつでも操作がそれが正常に読み込み、データベース、ファイルからの読み込み(待機が必要になるが起こる:あなたのサーバー(ここでは非常にリベラル擬似コード)のトップレベルには次のようになりますリクエストなど)、先物を使用して1つのスレッドをブロックしないので、パフォーマンスの高いシングルスレッドHTTPサーバーを使用できます。

今、あなたのアプリケーションの最高レベルは、上記のようなものだったし、いくつかの点で非常に低レベルでいくつかの要求がファイルから何かを読み取るために持っていた場合に何が起こるか想像してみてください。そのファイルを読むと未来が生まれるでしょう。その中間の層がすべて未来を処理しなかった場合は、ブロックする必要があり、目的を破ることになります。これは、先物がすべてかどうかという傾向があると言う理由です。

だから私の推測では、どちらかである:?

  1. あなたの友人は現在、非同期何かをすると、あなたは(まだそれをキャッチしていない彼が今までのファイルやデータベースか何かから読まないもしそうなら、彼はブロックしていますか? )。
  2. 彼はいつか非同期のことを計画していて、それを計画したいと思っていました。
  3. 彼は他の非同期フレームワークで多くの時間を費やし、正しく使用していなくてもスタイルを好きになった。
0

非同期コードの主なポイントは、継続コードを延期することです。

最も一般的なシナリオはI/Oで、操作が完了するのを待つのではなく、「あなたのことをやり終えたときに通知する」、またはより一般的には「あなたのことをやってあなたが終わったら "。

これはスレッドをまったく意味しません。ネットワークカードやハードドライブであれ、どんなデバイスからでも読み取るには、通常、デバイスからCPUに送信される何らかの信号や割り込みがあります。その間にCPUを使用することができます。 「notify me」は、ディスパッチループまたはスケジューラを実装する低レベルコードでより一般的です。 「これを行う」は、より高いレベルのコードでより一般的です。そこでは、あなたのためにディスパッチおよび/またはスケジュールされた確立されたライブラリまたはフレームワークを使用します。

あまり一般的でないシナリオには、スレッドをブロックせずに実行を延期すること(タイマと考えるとThread.sleep())と作業を分割することが含まれます。実際には、分割作業は複数のスレッドで非常に一般的です。オーバーヘッドがちょうど良く、オーバーヘッドである単一のスレッドでは、少しオーバーヘッドでパフォーマンスを向上させることができます。


あなただけの成功したか、非常に、本当に非同期ではなく、非同期コードのオーバーヘッドの一部であるかどうか、CompletableFuture Sを完成ビルド例として提供したコード。つまり、定義済みの非同期スタイルに従う必要があります。この場合、結果をすぐに提供できる場合でも、結果のメモリ割り当ては少量必要です。

これは、数千のコールで毎秒数百回、またはスレッド数が数十スレッドで数多くのスレッドで顕著になります。

場合によっては、事前定義された先物をたとえばnull01-1、空の配列/リスト/ストリーム、または他の非常に一般的な、あるいはあなたのドメイン内に特に存在する可能性のある固定された結果です。同様のアプローチは、結果だけでなく、結果が同じであるラッピングの将来をキャッシュすることです。しかし、私はあなたがこのように行く前に最初のプロフィールをお勧めします、あなたはおそらくボトルネックではないものを時期尚早に最適化するかもしれません。

関連する問題