我想用更高性能的東西替換未來實例列表。目前我正在遍歷樹並提交一個Callable來確定樹中每個節點的後代或自身節點的數量。我在一個列表保存未來的實例,然後得到一次所需的列表中選擇合適的節點計數:未來實例列表
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);
}
可悲的是,這是利用了列表的軸必須等待,直到所有的未來實例已提交。此外,它不會超出主存限制: -/
也許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中提供了許多實用的方法來幫助您做到這一點。 –
「功能實例」 - >您的意思是未來的實例,對吧? – jvdneste