2011-09-02 2 views
1

나는 Future-Instance 목록을 더 많은 성과물로 대체하고 싶습니다. 현재 트리를 탐색하고 Callable을 제출하여 트리의 각 노드에 대한 자손 또는 자체 노드 수를 확인합니다. 나는 목록에 미래 인스턴스를 저장하고 다음 번에 필요한 목록에서 해당 노드 수를 얻을 수있어 :Future-Instances 목록

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가 올바른 사용법 일 수 있습니다.

편집 : 이제 Future가 실행될 때마다 미래가 목록에 추가되는 PropertyChangeListener로 실제로 무언가를 만들 것이라고 생각합니다. 그런 다음 CountDownLatch를 1로 초기화하고 목록에 새로운 Future가 추가 될 때마다 countDown()을 호출합니다. 뭔가 같이 : doHasNext에서 다음

/** 
* {@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(); 
    } 
} 

() :

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 대신에 이제는 단순히 "깨끗한"솔루션 인 PropertyChangeListener 구현과 함께 BlockingQueue를 사용했습니다.

관련,

요하네스

+0

당신이 제출 한 코드를 많이 이해하지 못합니다 (Item.BUILDER는 무엇을합니까?), 그러나 목록이 너무 커서 들어 가지 않을 경우 가능한 해결책은 반복 가능한 iterables/iterators를 사용하도록 코드를 다시 작성하고 즉시 항목을 처리하는 것입니다. 구아바에는 com.google.common.collect.Iterables 및 com.google.common.collect.Iterators에서이 작업을 지원하는 많은 유틸리티 메소드가 있습니다. –

+0

"기능 인스턴스"-> 미래 인스턴스를 의미합니까? – jvdneste

답변

2

당신이 단지 completion service를 사용할 수 있습니까? 일단 제출되면, 첫 번째 미래를 처리 할 것입니다 ...

+0

아니, 순서대로 필요하기 때문에 관찰자 패턴과 BlockingQueue를 사용하는 것이 가장 좋은 방법이라고 생각합니다. 그것은 단지 파이프 일 뿐이며 분명히 빠릅니다. 이제 모든 항목이 생성되었을 때 변경 사항을 발생시키는 또 다른 병목 지점을 교체해야합니다. 이는 시간 낭비입니다. – Johannes

+0

특정 순서로 완료해야하는 경우, 일련 번호가 아닌가요? 즉, 왜 앞으로 각 차례를 기다리지 않을까요? 그 영향은 관찰자를 사용하는 것과 같은 것입니까? 그리고 더 간단하게 ..? 나는 일자리를 제출하는 것이 엄청난 간접비가되어서는 안되며, 각 직무가 끝날 때까지 기다리는 것이 더 중요 할 것이라고 생각합니다. – Toby

+0

큰 나무 (특히 1MB 이상 - 큰 나무라고 생각하면 큰 나무)에는 큰 차이가있는 것으로 보입니다. 2000 노드 정도의 노드라도 트리 탐색과 제출은 약 2 ~ 3 초 동안 지속되는 것처럼 보이기 때문에 명확하게 확장되는 것처럼 보이지만 벤치마킹하지 않았습니다. 그런 종류의 파이프 라인 방식으로 전체 프로세스의 속도가 향상됩니다. – Johannes