Future-Instances のリストをよりパフォーマンスの高いものに置き換えたいと思います。現在、ツリーをトラバースし、 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);
}
残念なことに、List を使用している軸は、すべての Future インスタンスが送信されるまで待機する必要があります。さらに、メインメモリの制限を超えてスケーリングしません:-/
おそらく、Google Guava と ListenableFuture を使用するのが適切でしょう。
編集:Futureが起動されるたびにFutureがリストに追加されるPropertyChangeListenerで実際に何かを構築すると思います。次に、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 の実装と組み合わせて使用しました。これは、優れた「クリーンな」ソリューションのようです。
よろしく、
ヨハネス