2011-12-18 3 views
0

결과를 정확한 순서로 요구하는 계산 (CTR 암호화)이 있습니다.Java : 비동기 작업에서 검색된 결과 주문

이 결과를 계산하는 멀티 스레드 디자인을 만들었습니다.이 경우 결과는 ByteBuffer입니다. 물론 계산 자체는 비동기 적으로 실행되므로 언제든지 어떤 순서로든 결과를 사용할 수 있습니다. "사용자"는 메서드를 호출하여 결과를 사용하는 단일 스레드 응용 프로그램이며, 그 후에 메서드는 ByteBuffers를 리소스 풀로 반환합니다. 리소스 관리는 이미 스레드 안전 스택을 사용하여 처리됩니다.

이제 질문 : 결과를 취합하여 오른쪽 순서에서 사용할 수있는 것이 필요합니다. 다음 결과를 사용할 수 없으면 사용자가 호출 한 메서드가있을 때까지 차단해야합니다. 누구든지 비동기 적으로 계산 된 결과를 순서대로 반환 할 수있는 java.util.concurrent의 좋은 전략이나 클래스를 알고 있습니까?

솔루션은 스레드로부터 안전해야합니다. 제 3 자 라이브러리 인 Thread.sleep()/Thread.wait()를 피하고 "synchronized"가 아닌 다른 관련 키워드를 피하고 싶습니다. 더구나, 작업은 예를 들어. 필요하다면 집행자를 올바른 순서로 선택하십시오. 이것은 연구용이므로 Java 1.6 또는 1.7 구조를 자유롭게 사용할 수 있습니다.

참고 : JRE 및 [암호화]에 정의 된 클래스 내에서 누군가가 이미 처리해야 할 수도 있으므로이 질문 [jre]에 태그를 지정했지만 질문 자체는 순전히 Java에 관한 것입니다. & 멀티 스레딩.

+0

왜 ByteBuffer 배열을 만들고 Bytebuffer를 스레드로 전달하지 않습니까? 모든 스레드가 완료되면 배열 순서대로 ByteBuffers를 작성하십시오. – fge

+2

암호화와 관련이 없으므로 '암호화'태그를 제거했습니다. –

답변

4

사용 executors framework 다음 listOfCallables 당신이 데이터에서 작동하도록 만들어 가지고 List<Callable<ByteBuffer>> 될 것

ExecutorService executorService = Executors.newFixedThreadPool(5); 
List<Future> futures = executorService.invokeAll(listOfCallables); 
for (Future future : futures) { 
    //do something with future.get(); 
} 
executorService.shutdown(); 

. 예를 들면 :

list.add(new SubTaskCalculator(1, 20)); 
list.add(new SubTaskCalculator(21, 40)); 
list.add(new SubTaskCalculator(41, 60)); 

(숫자의 임의의 범위 조정이 손에 당신의 작업에) 결과가 완료,하지만 동시에 다른 작업도 그렇게 때를, 실행 때까지

.get() 블록 도달하면 .get()이 준비됩니다.

+0

첫 번째 답변 중 하나가 될 것 같았습니다 (이전에 StackOverflow에서 다루었 기 때문에). 불행하게도, ByteBuffers는 사용 후에 사용 가능하게되고 다른 리소스가 사용 가능 해지면 다음 태스크를 해지해야합니다. 즉, 동시에 모든 작업을 수행 할 수는 없습니다. –

+0

+1을 사용합니다. @wlstead, 귀하의 회신을 이해하지 못합니다. "사용 후 사용 가능함"이란 의미는 무엇입니까? 한 번에 실행중인 작업 수를 제한 할 수 있습니다 (예제 코드에서는 5로 설정 됨). 작업 완료시 멋진 작업을 수행하는 CompletionServices가 있습니다. – user949300

+0

나는 그것을 얻지도 않았다. 다음 작업이 이전 작업에 따라 다르면 동 기적으로 수행하십시오. 다른 옵션이 없습니다. – Bozho

1

올바른 순서로 결과를 반환하는 것은 간단합니다. 각 결과가 도착하면 arraylist에 저장하고 일단 모든 결과를 얻으면 arraylist를 정렬하십시오. PriorityQueue를 사용하여 결과가 도착했을 때 항상 정렬 된 상태로 유지할 수는 있지만, 결과에 아무런 영향을 미치지 않기 때문에 아무 일도하지 않아도됩니다.

그래서, 당신이 할 수있는 것은 이것이다 :

들이 서수으로 분류 할 수 있도록, 당신의 bytearrays와 서수 중 하나를 포함하는 "WorkItem에서"클래스를 선언합니다.당신의 메인 쓰레드에서

...do work and produce a work_item... 

synchronized(LockObject) 
{ 
    ResultList.Add(work_item); 
    number_of_results++; 
    LockObject.notifyAll(); 
} 

같은 것을 수행합니다 : 작업 스레드에서

은 같은 것을 할 당신이 원하는에 대한 이해를 확보 한 후

synchronized(LockObject) 
    while(number_of_results != number_of_items) 
     LockObject.wait(); 
ResultList.Sort(); 
...go ahead and use the results... 
+0

감사합니다. MikeNakis.그러나 가능한 한 빨리 결과를 사용할 수 있도록하는 것이 좋습니다. 그렇지 않은 경우 사용자는 해당 시간에 필요한 결과 이외의 결과에 대해 계산이 수행되는 동안 차단됩니다. –

+0

그래,이 질문에 지정되지 않았습니다. 호출자가 결과를 생성하는 코드와 병행하여 결과에 대해 작업하고 다음 결과가 순서대로 작동하도록하려면 호출자가 작업 할 것이라고 말하고 있습니까? –

+0

바로! 알았어. –

0

내 새로운 답을 해야 할 일 :

바이트 수와 그 서수 중 하나가 포함 된 "WorkItem"클래스를 선언하여 서수로 정렬 할 수 있도록합니다.

서수로 정렬 된 java.util.PriorityQueue를 사용합니다. 기본적으로 우선 순위 대기열의 첫 번째 항목은 주어진 시간에 처리 할 다음 항목이됩니다.

각 작업 스레드는 PriorityQueue에 결과를 저장하고 일부 잠금 개체에 NotifyAll을 발급합니다.

주 스레드가 잠금 개체를 기다렸다가 큐에 항목이 있고 큐의 첫 번째 항목 (peeked, dequeued)의 서수가 지금까지 처리 된 항목 수와 같은 경우 , 항목을 대기열에서 제외하고 처리합니다. 그렇지 않다면, 그것은 계속 기다리고 있습니다. 모든 항목이 생성되고 처리되면 완료됩니다.

+0

이것은 매우 유망한 대답처럼 들리지만, 잠금 객체와 우선 순위 큐의 사용을 조사 할 것입니다. –

+0

몇 가지 코드를 시도했지만 잠금 개체와 함께 요소를 큐에 넣고 peeking/remove하는 경합 조건으로 계속 실행합니다. –

+0

멀티 스레딩은 쉽지 않습니다. PriorityQueue는 동기화되지 않으므로 사용자 자신의 동기화를 제공해야합니다. 물건을 잠그거나 물건에 접근 할 때 매우 신중해야합니다. wait()를 입력하기 전에 조건을 확인해야합니다. 그렇지 않으면 알림을받을 수 없습니다. wait()에서 깨어 난다고해서 기다리고 있던 상태가 일어난 것은 아니므로 일반적으로 조건이 실제로 유지 될 때까지 루프를 기다려야합니다. 이 문제를 해결할 수 없다면 코드를 게시하여 사람들이 문제를 발견하도록 도와 줄 수 있습니다. –

관련 문제