1

我想用性能更高的东西替换未来实例列表。目前我正在遍历一棵树并提交一个 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 的方式(尚未测试上述代码)。

编辑:以防万一有人感兴趣。我现在简单地将 BlockingQueue 与 PropertyChangeListener 的实现结合使用,而不是 CountDownLatch 和 List,这似乎是一个很好的“干净”解决方案。

问候,

约翰内斯

4

1 回答 1

2

你不能只使用完成服务吗?提交后,它将处理第一个未来以完成...

于 2011-09-04T18:27:18.700 回答