我想用更高效的东西替换未来实例列表 . 目前我正在遍历一棵树并提交一个Callable来确定树中每个节点的后代或自身节点的数量 . 我将Future实例保存在List中,然后在需要时从List获取适当的节点数:
try {
assert mIndex + 1 < mDescendants.size();
mItem =
Item.BUILDER.set(mAngle, mExtension, mIndexToParent).setParentDescendantCount(
mParDescendantCount).setDescendantCount(mDescendants.get(mIndex + 1).get()).build();
} catch (final InterruptedException | ExecutionException e) {
LOGWRAPPER.error(e.getMessage(), e);
}
令人遗憾的是,使用List的轴必须等到所有Future实例都已提交 . 此外,它不会超出主内存限制: - /
也许Google Guava和ListenableFuture是正确的选择 .
编辑:现在我想我实际上将使用PropertyChangeListener构建一些东西,每当触发Future时,Futures都会被添加到列表中 . 然后我将CountDownLatch启动为1,并在每次将新的Future添加到List时调用countDown() . 就像是:
/**
* {@inheritDoc}
*/
@Override
public boolean hasNext() {
if (mDescendants.size() > 0) {
return doHasNext();
} else {
try {
mLatch.await(5, TimeUnit.SECONDS);
} catch (final InterruptedException e) {
LOGWRAPPER.error(e.getMessage(), e);
}
return doHasNext();
}
}
然后在doHasNext()中:
try {
assert mIndex + 1 < mDescendants.size();
mItem =
Item.BUILDER.set(mAngle, mExtension, mIndexToParent).setParentDescendantCount(
mParDescendantCount).setDescendantCount(mDescendants.get(mIndex + 1).get()).build();
mLatch = new CountDownLatch(1);
} catch (final InterruptedException | ExecutionException e) {
LOGWRAPPER.error(e.getMessage(), e);
}
和听众:
/** {@inheritDoc} */
@SuppressWarnings("unchecked")
@Override
public void propertyChange(final PropertyChangeEvent paramEvent) {
Objects.requireNonNull(paramEvent);
if ("descendants".equals(paramEvent.getPropertyName())) {
mDescendants.add((Future<Integer>) paramEvent.getNewValue());
mLatch.countDown();
}
}
我不确定它是否有效,为时已晚,我不信任我使用CountDownLatch的方式(尚未测试上面的代码) .
编辑:以防有人感兴趣 . 而不是CountDownLatch和List我现在只使用BlockingQueue和PropertyChangeListener的实现,这似乎是一个很好的“干净”解决方案 .
问候,
约翰内斯
1 回答
你不能只使用completion service吗?一旦提交,它将处理第一个未来完成...