2016-06-16 6 views
0

同期メソッド呼び出しからCompletableFutureを作成するために1ライナーが存在するかどうかを知りたい。いいえ、なぜですか?同期メソッド呼び出しからCompletableFutureを作成する

ロングバージョン:

final CompletableFuture<ReturnType> future = new CompletableFuture<>(); 
final String parameters = "hello"; 
ReturnType result; 
try { 
    result = syncMethodCall(parameters); 
} catch (Exception e) { 
    future.completeExceptionally(e); 
} 
future.complete(result); 
return future; 

ショート目的のバージョン(または種類):

final String parameters = "hello"; 
return CompletableFuture.superMethod(() -> {syncMethodCall(parameters)}); 
+0

'CompletableFuture.completedFuture(syncMethodCall(parameters))' –

+0

@SotiriosDelimanol'SyncMethodCall'が例外をスローすると、この例外はCompletableFutureに格納されません。 –

+0

あなたの長いバージョンは問題ありません。それを短いバージョンに変換するには、Callable というタイプのパラメータを持つ独自の "superMethod"を定義するだけです。 –

答えて

0

あなたCompletableFutureは、いくつかのメソッド呼び出しの結果で終了し、あなたがしたくないことをしたいので、そのCompletableFutureを自分で完成させてください。それからCompletableFutureは必要ありません。将来の実装はOKです。例えば 、

T function(parameters) { 
    return new T(); 
} 
T res1 = function(parameters); // sync call 
Future<T> f = ForkJoinPool.commonPool.submit(() -> function(parameters)); // async call 
T res2 = f.get(); 
assert(res1.equals(res2)); 
+0

アレクセイ、ForkJoinPool、ありがとう! – user1660655

+0

なぜ長いバージョンではないソリューションがマルチスレッドでなければならないのですか? – user1660655

+0

@ user1660655 Future(およびCompletableFuture)を使用するとシーケンシャルワールドで意味をなさないため、マルチスレッド化されています。 –

2

あなたは非同期呼び出しを行い、答えを受け入れているので、あなたが最初の場所で「シンクロンメソッドの呼び出し」を求めた理由、それは不明です。非同期メソッド呼び出しを実行するタスクはCompletableFutureと非常に簡単です:あなたの意図はすでに戻ったときに完了することが、将来を強制することだった場合、それは簡単です

String parameters="hello"; 
return CompletableFuture.supplyAsync(() -> syncMethodCall(parameters)); 

は強制する:

String parameters="hello"; 
CompletableFuture<ReturnType> f = CompletableFuture.supplyAsync(
            () -> syncMethodCall(parameters)); 
f.handle((x,y) -> null).join(); 
return f; 

handlejoinの前の段階でsyncMethodCallが例外を投げた場合、joinはあなたの意図であると思われます。しかし、handleステージは返されず、代わりに記録された例外を持つ元の未来が返されます。現在の実装で呼び出し側のスレッド内ですべてを行うためのトリックがあること
注:

return CompletableFuture.completedFuture("hello") 
    .thenApply(parameters -> syncMethodCall(parameters)); 

将来がすでに完了したときにthenApplyに渡された関数はすぐに評価されます。しかし、依然としてsyncMethodCallによってスローされた例外は、返された将来に記録されます。結果はあなたの質問の「長いバージョン」と同じです。

+0

ありがとう。 私は最初の答えがわかりました(非同期でも)と私は最終的にForkJoinPoolを使用して私には良い(vertxのスレッドをしたいvertxアーキテクチャを使用して)ではないことに気づいた – user1660655

+0

例外処理についてはどうですか?コードはRuntimeExceptionsだけをスローする必要がありますか? – user1660655

+0

API全体が、チェックされた例外を許可しない機能的なインターフェイスを中心に構築されていることは恐れられます。あなたのメソッドがチェック例外を投げた場合、あなたはあなたの長いバージョンにとどまる必要があります。もちろん、長いバージョンを再利用可能なユーティリティメソッドにラップすることもできます。実際のアクションでは、チェックされた例外を許可する機能インタフェースを選択(または作成)する必要があります。 'Callable' ... – Holger

関連する問題