【发布时间】:2017-12-14 06:11:37
【问题描述】:
我调用一个返回Future 的方法,为List<Principal> 中的每个元素调用一次,所以我最终得到一个List<Future<UserRecord>>。
返回Future 的方法是库代码,我无法控制该代码的运行方式,我只有Future。
我想等待所有Futures 完成(成功或失败),然后再继续。
有没有比这更好的方法:
List<Principal> users = new ArrayList<>();
// Fill users
List<Future<UserRecord>> futures = getAllTheFutures(users);
List<UserRecord> results = new ArrayList<>(futures.size());
boolean[] taskCompleted = new boolean[futures.size()];
for (int j = 0; j < taskCompleted.length; j++) {
taskCompleted[j] = false;
}
do {
for (int i = 0; i < futures.size(); i++) {
if (!taskCompleted[i]) {
try {
results.add(i, futures.get(i).get(20, TimeUnit.MILLISECONDS));
taskCompleted[i] = true;
} catch (TimeoutException e) {
// Do nothing
} catch (InterruptedException | ExecutionException e) {
// Handle appropriately, then...
taskCompleted[i] = true;
}
}
}
} while (allNotCompleted(taskCompleted));
对于好奇的人:
private boolean allNotCompleted(boolean[] completed) {
for (boolean b : completed) {
if (!b)
return true;
}
return false;
}
与Waiting on a list of Future 的答案不同,我无法控制创建Futures 的代码。
【问题讨论】:
-
allNotCompleted(taskCompleted)sn-p 是否检查整个数组并返回整体结果? -
是的,当然。
-
你为什么在
get()上使用超时?它有什么用途,因为您将不断循环回到它。此外,“适当处理”在您的上下文中意味着什么,因为它对代码需要做什么和可以做什么有很大影响。您是 Java 新手,不是吗?您将boolean[]初始化为 false,即使它是默认值。 -
为什么这么复杂?
for (Future<UserRecord> future : futures) results.add(future.get());怎么了? -
@shmosel 也许是因为我只是想多了:-)。
标签: java concurrency java-8 future