2

나는 다음과 같은 상황이 있습니다생산자 - 소비자가 : 알리 알 어떻게 prodcution이 완료

    읽기 데이터베이스
  1. 의 데이터는 "계산"데이터베이스에
  2. 쓰기 결과를 작동합니까

나는 데이터베이스에서 읽은 스레드를 가지고 있으며 생성 된 객체를 BlockingQueue에 저장한다. 이러한 객체는 매우 무거운 가중치이므로 메모리에있는 객체의 양을 제한하는 대기열입니다. 여러 스레드가 큐에서 개체를 가져 와서 작업을 수행하고 두 번째 큐에 결과를 저장합니다. 마지막 스레드는 두 번째 큐에서 결과를 가져 와서 결과를 데이터베이스에 저장합니다.

문제는 교착 상태를 방지하는 방법입니다. "계산 쓰레드"는 더 이상 객체가 큐에 저장되지 않을 때를 알아야합니다. 현재 스레드 (참조 가능)의 참조를 서로 전달하고 폴링 또는 제안 전에 thread.isDone()을 확인한 다음 요소가 null 인 경우이를 수행합니다. 또한 큐의 크기를 확인합니다. 큐에 요소가있는 한 소비해야합니다. take 또는 put을 사용하면 교착 상태가 발생합니다.

더 간단한 방법이 있나요?

+0

은 http://stackoverflow.com/questions/5326013/proper-implementation-of-producer-consumer-scenario-and-graceful-termination-of의 속일 수 있습니다. –

답변

0

더 많은 작업이 대기열에 도착하지 않을 것이라고 확신 할 때 "더미"또는 "포이즌"메시지를 대기열의 마지막 메시지로 넣는 것이 좋습니다. 예를 들어 db 쿼리의 마지막 행과 관련된 메시지를 보냅니다. 따라서 생산자가 대기열에 더미 메시지를 넣으면이 더미 메시지를받는 소비자는 더 이상 의미있는 작업이이 배치에 필요하지 않음을 알게됩니다.

+0

내가 가진 것은 더 생산자 - 소비자/생산자 - 소비자 패턴. 중간 부분은 데이터를 소비 한 다음 결과를 다른 소비자에게 전달합니다. 문제는이 "중간 부분"의 인스턴스가 여러 개 있다는 것입니다. 이것은 열심히 일하는 곳입니다. 문제는 "더미 데이터"가 더미에 대한 작업이 없으므로 이전의 "실제 데이터"보다 빠르게이 체인을 통과 할 수 있다는 것입니다. –

+0

더미 데이터 또는 posion 메시지는 단지 교착 상태를 피하기위한 것이 었습니다. 그래서 더 이상 메시지가 도착하지 않을 것입니다. 이미 시작된 작업의 완료를 추적하기 위해 카운트 다운 래치 또는 무언가를 사용할 수도 있습니다. – Scorpion

0

어쩌면 당신은 CompletionService 집행을 결합하도록 설계

에서 모양과 하나의 큐 기능을해야합니다. 실행을 완료 작업 당신은 다시 당신이 completionServiceInstance에서 가져온 결과와 함께 공급됩니다 결과와 DB를 채우기 3. 즉 또 다른 집행을 사용할 수 있습니다

completionServiceInstance.take() 

를 통해 완성 서비스에서 사용할 수 있습니다.

+0

이것은 많은 작업을 처리하지 않고 데이터베이스에서 생성 한 개체이기 때문에 도움이되지 않습니다. 병렬로 실행해야하는 작업은 3 개뿐입니다. 1. 데이터베이스에서 읽는 중입니다. 2. 작업을 수행하십시오. 3. 결과를 데이터베이스에 씁니다. 읽기와 쓰기가 실제 작업보다 훨씬 빠르기 때문에 메모리 사용을 제한하기 위해서는 병렬 처리가 필요합니다. –