2012-08-02 4 views
1

서블릿 컨텍스트에 저장하는 ConcurrentHashMap이 있는데, 맵의 데이터가 동시에 변경됩니다. 서블릿 컨텍스트가 스레드로부터 안전하지만 ConcurrentHashMap (쓰기 용)이라는 것을 알고 있습니다. 이 경우 동기화 구성을 사용해야합니까? 상황이 종료 될 때까지 제거되지 않으므로서블릿의 ConcurrentHashMap

synchronized (context) { 
    ConcurrentHashMap messages =(ConcurrentHashMap)context.getAttribute("map"); 
    String mes = messages.get("id"); // can be changed by another thread? 
    messages.put("id",mes +"changed by thread 1"); 
    } 

답변

1

미안하지만 난 문제가 표시되지 않습니다. "messages"는이 예제에서 지역 변수이며, 모든 쓰레드는 하나를 가질 것입니다. 당신은 "컨텍스트"에서 읽을 때 발생할 수

유일한 문제를 "메시지"를 공유하지 않습니다 그래서, 당신은이

ConcurrentHashMap messages = null; 
synchronized (context) { 
    ConcurrentHashMap messages =(ConcurrentHashMap)context.getAttribute("map"); 
} 
String mes = messages.get("id"); // can be changed by another thread? 
messages.put("id",mes +"changed by thread 1"); 

를 읽을 수 있지만, 가장 좋은 것을 방지하는 것입니다 동기화해야 만합니다. 읽기 양식 컨텍스트에서 동기화를 피하는 방법은 무엇입니까? 간단하다, 당신은 문맥에 쓰거나 초기화 과정에서만 그렇게해서는 안된다.

1

ServletContext 내이 inits 때지도를 저장하는 경우에, 당신은 그것을 받고 동기화 할 필요가 없습니다.

지도가 동시성을 처리하는지 여부는 중요하지 않습니다. 후자의 경우에는 Map을 동기화해야하지만 동시성을 처리하는 하나를 사용할 때조차도이를 수행 할 필요가 없습니다.

+0

메시지를 받고 변경 한 순간에 이전 값을 기준으로이 이전 값을 다른 스레드 (감시 코드)가 변경할 수 있습니까? – Sergey

0

지도에 대한 참조가 보관 된 후 변경 사항에 대해 걱정할 경우 할 수있는 작업은지도 사본을 반환하는 메소드로 코드를 래핑하는 것입니다. 이 경우 복사 시간에서 Map의 스냅 샷을 보유하게됩니다. 변경 내용을 동기화 할 경우

완전히 당신은 Collections.syncrhonizedMap (...)를 사용할 수 있습니다