2013-09-02 2 views
0

나는 Java's ForkJoinTask과 헤어져 장기 실행 계산을했습니다.ForkJoinTask 완료 핸들러

Java's FutureTask은 템플릿 방법 done()을 제공한다. Overriding this method allows for "registering a completion handler".

ForkJoinTask에 대한 완료 처리기를 등록 할 수 있습니까? 내 응용 프로그램에서 스레드를 차단하고 싶지 않기 때문에

나는 질문입니다 -하지만 난 result = ForkJoinPool.invoke(myForkJoinTask) 또는 result = ForkJoinPool.submit(myForkJoinTask).get()에 대한 호출을 통해 계산 결과를 검색으로 내 응용 프로그램은 즉시 차단 스레드를해야합니다.

+0

_ "차단 스레드가 없길 원합니다 ..."_ - 좀 더 자세히 설명해주세요. _something_ 여러 스레드가 있으면 결과를 수집하고 그 결과를 얻기 위해 완료 될 때까지 기다려야합니다. –

답변

1

"잠금 해제"프로그래밍 http://en.wikipedia.org/wiki/Non-blocking_algorithm을 말하는 것 같습니까? FutureTask.get()이 현재 스레드를 차단하여 유휴 CPU를 남기는 경우가 있지만 ForkJoinTask.get() (또는 조인)은 CPU를 계속 사용하려고 시도합니다.

문제를 여러 개의 작은 영역 (ForkJoinTask)으로 나눌 수있는 경우에 적합합니다. 한 FJTask가 준비되지 않은 다른 작업의 결과를 내부적으로 기다리고 있다면 ForkJoinTask는 ForkJoinPool에서 수행 할 다른 작업 (Task)을 선택하여 그 작업을 실행합니다.

모든 작업이 CPU 바운드되기 전까지는 모든 CPU가 바쁘게 유지됩니다. 작업 중 일부가 외부 이벤트 (예 : 화성 탐사선으로 REST 호출 보내기)를 기다리는 경우 작동하지 않습니다. 또한 문제가 DAG으로 나타나야합니다. 그렇지 않으면 교착 상태가 발생할 수 있습니다. 그러나 이전에 작업을 포크로 묶을 때까지는 동일한 작업으로 잘 작동합니다. 마침내 포크로 작업에 참여하면 더 좋습니다.

그래서 get() 또는 join()을 Task 내에서 또는간에 호출하는 것은 그리 나쁘지 않습니다.

완료 처리기를 언급하여 문제를 해결했습니다. ForkJoinTask를 직접 구현하는 경우 RecursiveTask 또는 RecursiveAction을 살펴 볼 수 있습니다. compute()를 구현하면 각 작업의 결과를 반환하는 대신 compute() 함수의 끝에있는 일부 수집기로 쉽게 전달할 수 있습니다.

하지만 수집가가 동시에 호출됩니다 고려해야합니다! 값을 추가하거나 완료 카운트를 계산하려면 java.util.concurrent.atomic을보십시오. 동기화 된 블록을 사용하지 마십시오. 다른 모든 작업은이 단일 병목 현상을 기다려야하고 오직 하나의 CPU 만 작동합니다.

결과를 전파하는 데는 FJPool에서 처리하기 때문에 반환하는 것보다 더 많은 문제가 포함된다고 생각합니다. 또한 최종 결과가 어느 시점에서 결정되고 (외부와 의사 소통하기가) 어려워집니다.

관련 문제