1

2 つのスレッド t1 と t2 があります。どちらもいくつかの計算を行い、t1 と t2 が終了するまでメイン スレッドをブロックしようとしています。以下に示すように .awaitTermination() を使用しましたが、問題は、if ステートメントであるにもかかわらず、.awaitTermination() が無限ループに入ることです。

なぜそれが起こっているのかを見つけるのを手伝ってください。t1 と t2 が終了するのに必要な正確な時間を知らずに時間を指定する必要がありますか?

 executor.execute(new RunnableClass(bgr,3))
 executor.execute(new RunnableClass(bgr,7))
 executor.shutdown();

if (executor.awaitTermination(3, TimeUnit.SECONDS)) {
    print("terminated")
}
4

3 に答える 3

5

Java 8 を使用している場合は、CompletableFuture<T>代わりに使用できます。join などの便利なメソッドを定義して実行を待機し、それらを連鎖させます。あなたの例は次のようになります。

final CompletableFuture<Void> future1 = CompletableFuture.runAsync(new RunnableClass(bgr, 3), executor);
final CompletableFuture<Void> future2 = CompletableFuture.runAsync(new RunnableClass(bgr, 7), executor);
CompletableFuture.allOf(future1, future2).join(); // blocks until both finished
executor.shutdown();

優れた紹介はここにあります。

于 2015-05-03T15:10:27.433 に答える
1

まず第一に、 に渡す時間awaitTerminationはおおよその値であり、すべてのタスクを完了するのにかかった最悪の累積時間よりも常に長くなる必要があります。それらのランナブルで実行しているのが Web サービス呼び出しまたは DB 呼び出しである場合、サイトのトラフィックに基づいて異なる可能性があるため、一定の時間を推測しないのは簡単ではありません。そのため、特定の時間内に常に完了すると想定するのではなく、すべてのランナブルが完了するのを待ってから、それらの結果を利用し始める必要があります。

CompletableFutureJava8 から使用できず、プールに送信されたすべてのランナブルが実行されるまで待機する必要がある場合は、以下のようinvokeAllに onを使用できExecutorServiceます。

invokeAll送信されたすべての callable が実行されるまで、メイン スレッドをブロックします。

// removing try-catch blocks for brevity
ExecutorService service = Executors.newFixedThreadPool(2);
List<Callable<Integer>> tasks = new ArrayList<>();
tasks.add(new Callable<Integer>(){
     public Integer call(){
                Thread.sleep(5000);
                System.out.println("thread1 coming out of sleep");
                return 1;
     }
});

tasks.add(new Callable<Integer>(){
    public Integer call(){
            Thread.sleep(10000);
            System.out.println("thread2 coming out of sleep");
            return 2;
    }
});

List<Future<Integer>> futures = service.invokeAll(tasks);
System.out.println("back in main");

service.shutdown();
service.awaitTermination(20,TimeUnit.SECONDS);

出力:

thread1 coming out of sleep
thread2 coming out of sleep
back in main
于 2015-05-03T17:40:54.267 に答える