Future.get()ブロックへのメソッド呼び出し。それは本当に望ましいことなのか?
質問
重複としてマークする前に、質問をよく読んでください。
以下は擬似コードのスニペットです。 私の質問は、以下のコードは並列非同期処理の概念そのものを打ち壊すものではないのでしょうか?
私がこれを尋ねる理由は、以下のコードでメインスレッドが別のスレッドで実行されるタスクを送信するためです。キューでタスクを送信した後、タスクが値を返すために Future.get() メソッドでブロックします。私は、タスクを別のスレッドにサブミットして結果を待つよりも、むしろメインスレッドで実行させたいと考えています。新しいスレッドでタスクを実行することによって、私は何を得ることができますか?
限られた時間だけ待つなどの方法があることは承知していますが、それでは本当に結果を気にする場合はどうすればよいのでしょうか?実行するタスクが複数ある場合、問題はさらに悪化します。同期的に作業を行うだけのような気がします。私は、非ブロッキングリスナーインターフェースを提供するGuavaライブラリの存在を知っています。しかし、私はFuture.get()APIについて私の理解が正しいかどうかを知りたいと考えています。もし正しいのであれば、なぜFuture.get()はブロックするように設計されており、それによって並列処理の全プロセスが台無しになるのでしょうか?
注 - 記録のために、私は JAVA 6 を使用しています。
public static void main(String[] args){
private ExectorService executorService = ...
Future future = executorService.submit(new Callable(){
public Object call() throws Exception {
System.out.println("Asynchronous Callable");
return "Callable Result";
}
});
System.out.println("future.get() = " + future.get());
}
どのように解決するのですか?
Future
は、以下の方法を提供します。
isDone()
これはブロックされず、計算が完了すれば真を、そうでなければ偽を返します。
Future.get()
は計算の結果を取得するために使用されます。
いくつかのオプションがあります。
-
コール
isDone()
を呼び、結果が準備できたらget()
ブロックがないことに注意してください。 -
で無期限にブロックします。
get()
-
指定されたタイムアウトの間、ブロックする。
get(long timeout, TimeUnit unit)
全体
Future API
は、並列タスクを実行するスレッドから値を取得する簡単な方法を提供するためにあります。これは、上記の箇条書きで説明されているように、同期でも非同期でも可能です。
キャッシュを用いた更新の例
以下は、キャッシュの実装を
Java並行処理の実践
の優れた使用例です。
Future
.
- 計算がすでに実行されている場合、計算結果に関心のある呼び出し側は計算の終了を待ちます。
- 結果がキャッシュに準備されている場合、呼び出し元はそれを収集します。
-
結果が準備できておらず、まだ計算が始まっていない場合、呼び出し元は計算を開始し、結果を
Future
でラップします。
これはすべて、簡単に
Future
APIで簡単に実現できます。
package net.jcip.examples;
import java.util.concurrent.*;
/**
* Memoizer
* <p/>
* Final implementation of Memoizer
*
* @author Brian Goetz and Tim Peierls
*/
public class Memoizer <A, V> implements Computable<A, V> {
private final ConcurrentMap<A, Future<V>> cache
= new ConcurrentHashMap<A, Future<V>>();
private final Computable<A, V> c;
public Memoizer(Computable<A, V> c) {
this.c = c;
}
public V compute(final A arg) throws InterruptedException {
while (true) {
Future<V> f = cache.get(arg);
// computation not started
if (f == null) {
Callable<V> eval = new Callable<V>() {
public V call() throws InterruptedException {
return c.compute(arg);
}
};
FutureTask<V> ft = new FutureTask<V>(eval);
f = cache.putIfAbsent(arg, ft);
// start computation if it's not started in the meantime
if (f == null) {
f = ft;
ft.run();
}
}
// get result if ready, otherwise block and wait
try {
return f.get();
} catch (CancellationException e) {
cache.remove(arg, f);
} catch (ExecutionException e) {
throw LaunderThrowable.launderThrowable(e.getCause());
}
}
}
}
関連
-
NullPointerException - java.lang.
-
SLF4J: クラス・パスに複数のSLF4Jバインディングが含まれています。
-
java -jarコマンドでパッケージを実行すると、無効または破損したjarfile xxxx.jarが表示される。
-
eclipse 実行 Java、エラー: 選択を起動できず、レシーバーもありません。
-
Javaがエラーで実行される、選択が起動できない、最近起動したものがない
-
git pull appears現在のブランチに対するトラッキング情報がありません。
-
switch case文のcaseの後の列挙定数は列挙型なし
-
swagger2 モデルが表示されない モデルが見つからない @ApiModel アノテーションが表示されない問題
-
[解決済み] Androidで遅延後にメソッドを呼び出す方法
-
[解決済み] モックされたメソッドに渡された引数を返すようにする
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
XMLファイル操作時のjava.util.NoSuchElementExceptionを解決する方法。
-
Javaでよくある構文エラー
-
Javaクラスが "Error occurred during initialization of boot layer "というエラーで実行される。
-
名前 'XXX' を持つ Bean の作成に失敗しました。自動依存関係の注入に失敗しました 解決方法
-
Javaジェネリックを1つの記事で
-
代入の左辺は変数でなければならない 解答
-
ecplise プロンプトが表示されます。"選択したものは起動できません。" "最近の起動はありません。"
-
switch case文のcaseの後の列挙定数は列挙型なし
-
swagger2 モデルが表示されない モデルが見つからない @ApiModel アノテーションが表示されない問題
-
[解決済み] Javaエグゼキュータ:タスクの完了をブロックせずに通知する方法とは?