5

こんにちは、CompletableFuture とデフォルトForkJoinPoolで、クラシックよりもタスクの実行を最適化できると思いましたが、ExecutorService何かが欠けています

このコードでは、実行に 1 秒かかります。3 つのワーカー スレッドがあります。

for (int i = 0; i < 3; i++) {
    final int counter = i;
    listTasks.add(CompletableFuture.supplyAsync(() -> {
        Thread.sleep(1000);
        System.out.println("Looking up " + counter + " on thread " + Thread.currentThread().getName());
        return null;
    }));
}

OK、正常に見えます。

しかし、このコードでは 3 秒かかります。

for (int i = 0; i < 9; i++) {
    final int counter = i;
    listTasks.add(CompletableFuture.supplyAsync(() -> {
        Thread.sleep(1000);
        System.out.println("Looking up " + counter + " on thread " + Thread.currentThread().getName());
        return null;
    }));
}

他の待機中のタスクを起動するためにスリープ スレッドが使用されると思っていましたが、これも 1 秒かかるはずです。たとえば、IO WAINTING スレッド状態は、スレッドを他のタスクに再利用できることを意味することを読みました。この動作を でテストできますThread.sleep()か? テスト方法が間違っているのでしょうか、それとも何かを間違って理解したのでしょうか?

4

2 に答える 2

4

スリープ状態のスレッドを使用して、別のスレッドのジョブを実行することはできません (特に、あるスレッドが別のスレッドのためにスリープ状態になることはありません)。最初のスレッドがスリープ状態になったときに、2 番目のスレッドに切り替えることができるのは CPU だけです。

にタスクを提供すると、コンピューターの CPU と同じ数のスレッドを持つCompletableFuture.supplyAsync()の既定のインスタンスにタスクが移動します。ForkJoinPool割り当てられた 3 つのスレッドを default に手動で設定したForkJoinPoolため、9 つのタスクがそれらの間で均等に分散されます。各スレッドは 3 つのタスクを連続して実行します。したがって、結果は 3 秒です。

于 2016-08-26T15:46:28.230 に答える