0

idMap 동기화 문제가 있습니다. 이지도는 동시에 실행되는 두 개의 run() 메소드에서 사용되고 있습니다. 첫 번째 run() 메소드에서는 단순히 이벤트 id 값을 응답 ID (key)에 매핑합니다. 두 번째 run() 메소드에서 동일한 응답 ID (키)로 이벤트 ID (값)를 얻고 싶습니다. 그러나 때로는 일부 이벤트 ID가 있고 때때로 얻을 수 없습니다. 이 프로그램은 잘 컴파일하지만, 나는 스레딩 전문가가 아니며 스레딩이 동기화되지 않아 idMap이 원인이라고 생각합니다. 제 질문은 단순히 idMap을 원활하게 작동시키고 의도 한대로 이벤트 ID를 얻으려면 어떻게해야합니까?스레딩에서 Hashmap 동기화

ConcurrentHashMap<String, String> idMap = new ConcurrentHashMap<String, String>(); 
ConcurrentHashMap<String, ExecutorService> executors = new ConcurrentHashMap<String, ExecutorService>(); 

private final class ResponderTask implements Runnable { 
    private ResponderTask(Event event) { 
     this.event = event; 
    } 
    // 1st run()  
    public void run() { 
     idMap.put(response.getId(), event.getId()); 
    } 
}//end ResponderTask 

private final class QuoteTask implements Runnable { 
    //constructor 
    //2nd run() 
    public void run() { 
     IdMap.get(response.getId()); 
    } 
}//end QuoteTask 

public void onResponse(final Response response) { 

    ExecutorService quoteExecutor = executors.get(response.getId()); 
    if (quoteExecutor == null) { 
     quoteExecutor = Executors.newSingleThreadExecutor();     
     executors.put(event.getId(), quoteExecutor);    
    } 
    quoteExecutor.execute(new ResponderTask(event)); 
} 
+1

: 당신이 종료하면 응용 프로그램을 수행 할 때 나는 다음과 같은 일을한다고 가정 java/util/concurrent/ConcurrentHashMap.html # get (java.lang.Object)) 정의를 사용하면 예상대로 키 값이 나타날 때까지 기다리지 않습니다. 이 작업을 수동으로 수행해야하는 것 같습니다. –

+0

'response'와'event'는 같은 필드로되어 있습니까? – Gray

답변

0

그러나, 시간에 몇 가지 이벤트 ID가 때때로 그들이 얻을 수 없다. 이 프로그램은 잘 컴파일하지만, 나는 스레딩 전문가가 아니며 스레딩은이 idMap이 동기화되지 않은 것으로 생각합니다.

idMap은 적절하게 동기화되어 있으며 많이 사용되어 많은 사람들이 테스트했습니다. 이드가지도를 볼 때지도에 없다면 거기에 놓여 있지 않습니다. 코드에 대해 조금 더 설명하면 문제를 찾을 수 있습니다.

예를 들어 response 개체의 출처가 표시되지 않습니다. ResponseTask이 다른 응답을 처리하고있을 가능성이 있습니까? responseevent이 같은 인수로 간주됩니까?

간단히 말해서 idMap을 원활하게 만들고 이벤트 ID를 얻으려면 어떻게해야합니까?

프로그램의 올바른 작동이 무엇인지 알아내는 것은 약간 어렵습니다. 이벤트를 얻기 위해 다른 스레드를 찾고 있다면 BlockingQueue을 사용할 수 있습니다. 그런 다음 다른 스레드가 queue.take()을 처리 할 수 ​​있으며 처리 할 이벤트가있을 때까지 대기합니다. 그러나 나는 목표가 무엇인지 확실하지 않습니다.

은 매우입니다. 단 하나의 것은 ExecutorService의지도를 사용하는 것입니다. 당신은 정말로 그들 중 다수가 필요합니까? 나는 당신이 정말로 하나의 Executors.newCachedThreadPool()을 사용해야한다고 생각합니다. 그러나 동일한 ID를 가진 모든 요청에 ​​대해 단일 스레드가 작동하기를 원한다면 코드가 작동해야합니다. [`ConcurrentHashMap의 # get`] (http://docs.oracle.com/javase/7/docs/api/에서

for (ExecutorService executor : executors.values()) { 
    executor.shutdown(); 
}