1

このコードを使用して、数百のタスクを異なる CPU コアに分割しています。

    final List<Throwable> errors = Collections.synchronizedList(Lists.<Throwable>newArrayList());

    final ExecutorService pool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

    for (...) {

        pool.execute(new Runnable() { @Override public void run() {

            try {

                // TASK HERE

            } catch (Throwable e) {
                errors.add(e);
            }

        }});

    }

    pool.shutdown();
    try {
        pool.awaitTermination(1000, TimeUnit.DAYS); // wait "indefinitely"
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }

    if (!errors.isEmpty()) throw Exceptions.wrap(errors.get(0)); // TODO multi-exception

動作しますが、良くありません。

  • awaitTermination私が欲しいタイムアウトなしのバージョンはありません。
  • 独自のエラー収集を行う必要があります。

これを行う適切な/一般的な方法は何ですか?

4

3 に答える 3

3

スレッド プールのポイントは、スレッドを再利用することです。アプリケーションの起動時に、タスクを作成するコードの外で作成し、注入する必要があります。タスクを追加した後にプールをシャットダウンする必要はありません。これは、アプリケーションのシャットダウン時に行います。

一連のタスクを実行するには、 を使用しますExecutorService.invokeAllget後で結果を取得するには、返されたそれぞれを呼び出しますFutures。タスクがスローした例外は再スローされるため、後で収集できます。

于 2012-08-08T09:37:45.857 に答える
1

future を使用してエラー処理を行うことができます。

final List<Future> futures = new ArrayList<Future>();
for (int i = 0; i < 5; i++) {

    futures.add(pool.submit(new Runnable() { @Override public void run() {
            // TASK HERE
    }}));

}

for (Future f : futures) {
    try {
        f.get();
    } catch (ExecutionException e) {
        //something bad happened in your runnable
    }
}

//when you are done with the executor

pool.shutdown();
try {
    pool.awaitTermination(1000, TimeUnit.DAYS); // wait "indefinitely"
} catch (InterruptedException e) {
    throw new RuntimeException(e);
}
于 2012-08-08T09:38:21.540 に答える
0

各 Runnable を送信し、 Futureを取得してから、各 Future でget()を呼び出す必要があると思います。

を呼び出すとget()、Runnable の結果、または発生した例外のいずれかを取得します。

于 2012-08-08T09:38:13.940 に答える