私はこの質問に答えました:Executing Dependent tasks in parallel in Java future.get()を使用して現在のスレッドをブロックしています。一度にたくさんのgets()が呼び出されます。 Javaの先物から先物をどのように構成するのですか?ブロッキングなしでJava 8で依存するタスクを実行する方法
4
A
答えて
3
私は自分自身でこの質問に答えると思っていました.Futuresの代わりにJavaでCompletableFuturesを使用することができます。 CompletableFuturesは、scalasのflatMapに似ているthenCombineメソッドによる合成を可能にします。今やブロッキングは発生せず、最速の時間を達成するためには3つのスレッドしか必要ありません。
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.BiFunction;
import java.util.function.Supplier;
public class Barrista
{
// number of threads used in executor
static final int NOTHREADS = 3;
// time of each task
static final int HEATWATER = 1000;
static final int GRINDBEANS = 1000;
static final int FROTHMILK = 1000;
static final int BREWING = 1000;
static final int COMBINE = 1000;
// method to simulate work (pause current thread without throwing checked exception)
public static void pause(long t)
{
try
{
Thread.sleep(t);
}
catch(Exception e)
{
throw new Error(e.toString());
}
}
// task to heat some water
static class HeatWater implements Supplier<String>
{
@Override
public String get()
{
System.out.println("Heating Water");
pause(HEATWATER);
return "hot water";
}
}
// task to grind some beans
static class GrindBeans implements Supplier<String>
{
@Override
public String get()
{
System.out.println("Grinding Beans");
pause(GRINDBEANS);
return "grinded beans";
}
}
// task to froth some milk
static class FrothMilk implements Supplier<String>
{
@Override
public String get()
{
System.out.println("Frothing some milk");
pause(FROTHMILK);
return "some milk";
}
}
// task to brew some coffee
static class Brew implements BiFunction<String,String, String>
{
@Override
public String apply(String groundBeans, String heatedWater)
{
System.out.println("Brewing coffee with " + groundBeans + " and " + heatedWater);
pause(BREWING);
return "brewed coffee";
}
}
// task to combine brewed coffee and milk
static class Combine implements BiFunction<String,String, String>
{
@Override
public String apply(String frothedMilk, String brewedCoffee)
{
System.out.println("Combining " + frothedMilk + " "+ brewedCoffee);
pause(COMBINE);
return "Final Coffee";
}
}
public static void main(String[] args)
{
ExecutorService executor = Executors.newFixedThreadPool(NOTHREADS);
long startTime = System.currentTimeMillis();
try
{
// create all the tasks and let the executor handle the execution order
CompletableFuture<String> frothMilk = CompletableFuture.supplyAsync(new FrothMilk(), executor);
CompletableFuture<String> heatWaterFuture = CompletableFuture.supplyAsync(new HeatWater(), executor);
CompletableFuture<String> grindBeans = CompletableFuture.supplyAsync(new GrindBeans(), executor);
CompletableFuture<String> brew = heatWaterFuture.thenCombine(grindBeans, new Brew());
CompletableFuture<String> coffee = brew.thenCombine(frothMilk, new Combine());
// final coffee
System.out.println("Here is the coffee:" + coffee.get());
// analyzing times:
System.out.println("\n\n");
System.out.println("Actual time: \t\t\t\t" + (System.currentTimeMillis() - startTime)/1000.0);
// compute the quickest possible time:
long path1 = Math.max(GRINDBEANS, HEATWATER)+ BREWING + COMBINE;
long path2 = FROTHMILK + COMBINE;
System.out.println("Quickest time multi-threaded:\t\t" + Math.max(path1, path2)/1000.0);
// compute the longest possible time:
long longestTime = HEATWATER + GRINDBEANS + FROTHMILK + BREWING + COMBINE;
System.out.println("Quickest time single-threaded thread:\t" + longestTime/1000.0);
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
executor.shutdown();
}
}
}
2
は、Java 8はあなたが完了段階に依存コールバックをトリガーする以外、特に、get
コールをブロックする必要はありませんCompletableFutureを、紹介します。明示的(その値と ステータスを設定)が完了してもよいし、その終了時にトリガー依存 機能および行動を支持する、CompletionStageとして使用することができる
A未来。 Javaの8の前にdocumentation
上
読むより、この概念はdocumentationとスプリングライブラリtooで続きを読む、Googleのグルーヴィーなライブラリで利用可能です。
+0
ありがとうございます。私はこれらを私の答えに使用しました。質問をするときに私はこの質問の答えを用意していましたが、それは人々にとって役に立つと思いました。私はこれを行う方法を見つけるのは非常に苦労しました。 – Snickers3192
関連する問題
- 1. SBT 0.10で他のタスクに依存してコードを実行する方法は?
- 2. SpringブロッキングとJavaで非ブロッキングREST 8
- 3. お互いに依存しているiOSで実行中のタスクを実行する方法
- 4. Javaで非ブロッキング先物を実装する方法
- 5. Java 7:並列タスクをバッチで実行する方法は?
- 6. スレッド・ブロッキングのないサブプロセスによる非同期タスクの実行
- 7. AndroidでPingタスクを実行するJava
- 8. 無効なタスクのGradleでの依存関係実行をスキップしますか?
- 9. ヘッドレスセレンスクリプトをホストとブラウザに依存しないで実行する方法
- 10. UNIX依存のタスクの実行
- 11. 他のタスクに依存するCompletableFutureを実行
- 12. パラレルで依存データベースクエリを実行する
- 13. 異なるコマンドで2つのタスクを実行する方法
- 14. JavaでUTF-8エンコーディングでテキストファイルを保存する方法は?
- 15. Java 8を使用してSpring 4でqueryForListを実行する方法は?
- 16. PERTダイアグラムで効率的なタスクの依存関係をモデル化する方法
- 17. C#タスクをシーケンスで実行する効率的な方法
- 18. のGradle:タスクの設定は、別のタスクの実行に依存
- 19. データベースなしでJavaで結合を実行する方法
- 20. データベースエンジンに依存しないページングを実装する方法は?
- 21. Rails 3.1でレンダリングした後にタスクを実行する方法
- 22. 親タスクが-cオプションで呼び出された場合の依存タスクの実行方法
- 23. Javaで.group()を実行する方法
- 24. Java TimerTask内で遅延なしでタスクを連続して実行する
- 25. Xcode 8とSierraでgfortranをセットアップして実行する方法
- 26. Javaで定期的にタスクを実行するより良い方法
- 27. Javaコールバックで依存関係注入を使用する方法
- 28. Javaアプリケーションで状況依存ヘルプを作成する方法
- 29. ビルドファイルなしでJavaプロジェクトを実行する方法
- 30. Gradleでクリーンでタスクを実行する方法
通常、「.get()」はバリアです。結果が得られない場合は、それ以上計算することはできません。 –
はい、先物から先物を構成することはできますが、回答を参照してください。 – Snickers3192
https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.htmlを参照してください。それは逐次実行を行うことができます。 –