【发布时间】:2011-11-09 12:36:54
【问题描述】:
我想用更高效的东西替换未来实例列表。目前我正在遍历一棵树并提交一个 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 添加到列表时调用 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 的实现结合使用,这似乎是一个很好的“干净”解决方案。
问候,
约翰内斯
【问题讨论】:
-
我不太了解您提交的代码(Item.BUILDER 是做什么的?),但是,如果您的 List 太大而无法放入内存,一个可能的解决方案是重写您的代码改为使用迭代器/迭代器,并动态处理您的项目。 Guava 在 com.google.common.collect.Iterables 和 com.google.common.collect.Iterators 中有许多实用方法来帮助解决这个问题。
-
"feature instance" -> 你的意思是 Future 实例,对吧?
标签: java concurrency guava future executorservice