2

以下が正しい実装になるのだろうか

    ExecutorService pool = Executors.newFixedThreadPool(MAX_NSH_THREADS);
    Set<Future<Void>> futureRequest = new HashSet<Future<Void>>();

    for (String host : SomeCollection)) {
        Callable<Void> callable = new FileExtractor(j);
        Future<Void> future = pool.submit(callable);
        futureRequest.add(future);
    }

    for (Future<Void> future : futureRequest) {
        try {
            future.get(); 
        } catch (Exception e) {
            logger.error(e);
        }
    }

    pool.shutdown();

Javadoc によると、future.get()スレッドごとに実行が完了するのを待ちます。これは、(私が理解しているように) それぞれの将来について、結果を個別に受け取るのを待つことを意味します。その利益はどこから来るのですか、それとも私はそれを正しくしていませんか?

4

2 に答える 2

4

あなたはそれを正しくやっています。

SomeCollection100 個のアイテムが含まれFileExtractorていて、実行に 5 秒かかり、ExecutorServiceスレッド プールに 100 個のスレッドが含まれているとします。

FileExtractor上記で実装したとおりに開始すると、 I/O バウンドになる可能性が高いため、コードが約 5 秒間実行されることが予想されます。(最大の CPU 効率を想定)。

を使用せずFuture、すべてをシリアルに実行した場合、このコードは代わりに約 500 秒間実行されます。

重要なのは、メソッドで待機するのではなく、 に送信することによって開始されFuture#get()た によって結果が取り込まれるのを待機することです。ThreadCallableExecutorServiceExecutorService#submit(Callable)

于 2012-01-17T21:59:23.887 に答える
2

それぞれの未来は、あなたがそれを提出するとすぐに、を呼び出すことによって開始されますpool.submit。その間に(先物を開始してから終了するまでの間)メインスレッドに他の作業があった場合、2番目のループに到達するまでにすべての先物が完了している可能性があります。ブロッキングしないでください。

また、getメソッドがメインスレッドをブロックする場合、最初のスレッドが終了するのを待っている間、他のスレッドFutureはまだ並列に実行されていることに注意してください(少なくとも潜在的には、十分なプロセッサ時間が与えられます)。

于 2012-01-17T22:01:07.497 に答える