未来实例列表
我想用性能更高的东西替换未来实例列表。目前,我正在遍历一棵树并提交一个 Callable 来确定树中每个节点的后代或自身节点的数量。我将 Future 实例保存在列表中,然后在需要时从列表中获取适当的节点计数:
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);
}
可悲的是,使用列表的轴必须等到所有 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 的实现结合使用,这似乎是一个很好的“干净”解决方案。
问候,
约翰内斯
I'd like to replace a List of Future-Instances with something more performant. Currently I'm traversing a tree and submit a Callable to determine the number of descendant-or-self nodes for each node in the tree. I'm saving the Future instance in a List and then get the appropriate node count from the List once required:
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);
}
The sad thing is that the axis which is making use of the List has to wait until all Future instances have been submitted. Furthermore it doesn't scale beyond main memory limits :-/
Maybe Google Guava and ListenableFuture is the right thing to use.
Edit: Now I think I'll actually build something with a PropertyChangeListener where Futures are added to a list whenever a Future is fired. Then I initiate a CountDownLatch to 1 and call countDown() everytime a new Future is added to the List. Something like:
/**
* {@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();
}
}
then in 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);
}
and the Listener:
/** {@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();
}
}
I'm not sure if it works, it's too late and I mistrust the way I would use the CountDownLatch (haven't tested the above code).
Edit: Just in case someone is interested. Instead of the CountDownLatch and a List I now simply used a BlockingQueue in conjunction with the implementation of a PropertyChangeListener, which seems to be a good, "clean" solution.
regards,
Johannes
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
难道你不能只使用完成服务?提交后,它将处理第一个未来完成的......
Can't you just use a completion service? Once submitted, it'll process the first future to complete...