我正在使用此代码在不同的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
版本,这就是我想要的。这样做的正确/常用方法是什么?
答案 0 :(得分:3)
线程池的重点是重用线程。您应该在应用程序启动时创建它,在创建任务的代码之外创建它并注入它。添加任务后无需关闭池。您在应用程序关闭时执行此操作。
要运行任务集合,请使用ExecutorService.invokeAll
。要在之后获得结果,请在每个返回的get
上调用Futures
。它将重新抛出任务抛出的任何异常,因此您可以在之后收集它。
答案 1 :(得分: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);
}
答案 2 :(得分:0)