2011-09-02 2 views
0

채팅 응용 프로그램을 개발 중입니다. 채팅 메시지를 처리하는 기능이 있습니다. 각 대화방은 고유 단축 코드으로 식별됩니다. 이제는 하나의 shortcode에 대한 메시지가 처리 될 때 다른 shortcodes에 대한 메시지가 계속 수행되어야하는 동안 동일한 shortcode에 대한 다른 메시지가 대기해야합니다.Java 동기화 문제 - 여러 채팅방 응용 프로그램 채팅

같은 짧은 코드에 대한 메시지가 병렬로 처리되므로 코드의 평화를 고려해보십시오. 문제는 무엇입니까? 난 그냥 볼 수

private HashMap<String, Object> locks = new HashMap<String, Object>(); 

public void handleShortCode(String shortcode,String message,String from) 
{ 
    Object lock = null; 

    lock = locks.get(shortcode); 
    if (lock == null) 
    { 
     locks.put(shortcode, lock = new Object()); 
    } 

    synchronized (lock) 
    { 
     System.out.println("Handling shortcode:" + shortcode); 
     // processing 
     System.out.println("Successfully handled shortcode:" + shortcode + " ......"); 
    } 
} 

답변

4

첫 번째 이유는 너무 여러 스레드가 동시에 실행할 수 있습니다, 여기

Object lock = null; 

lock = locks.get(shortcode); 
if (lock == null) 
{ 
    locks.put(shortcode, lock = new Object()); 
} 

어떤 뮤텍스 외부에서 실행되는 코드의이 블록 문제를 추측, 각각의 수 (동일한 단축 코드를 가짐) 은 자신의 자물쇠가인데, 서로 독립적입니다 (그리고 그 중 하나만이 해시 맵에 저장됩니다 - 일반적인 HashMap이 동시 사용을 위해 설계되지 않았기 때문에 하나의 질문입니다. 실제로 어떤 "넣기"가 어떤 순서로 영향을 미칠지 예측할 수 없으며 심지어 예외적이거나 잘못된 행동을 취할 수도 있습니다 이 코드에서는, 현재의 puts가 크기 변경의 원인이되는 경우). 각 스레드는 자신의 잠금을 얻으므로 다른 스레드와 병행하여 다른 잠금을 얻는 것을 막지 않습니다.

간단한 (하지만 매우 효율적이지) 방법은 문제를 해결하기 :

private HashMap<String, Object> locks = new HashMap<String, Object>(); 
private final Object hashmapLock = new Object(); 
public void handleShortCode(String shortcode,String message,String from) 
{ 
    Object lock = null; 
    synchronized(hashmapLock){ 
     lock = locks.get(shortcode); 
     if (lock == null) 
     { 
      locks.put(shortcode, lock = new Object()); 
     } 
    } 
    synchronized (lock) 
    { 
     System.out.println("Handling shortcode:" + shortcode); 
     // processing 
     System.out.println("Successfully handled shortcode:" + shortcode + " ......"); 
    } 
} 

이 방법 당신은 단축 코드 당 정확히 하나의 잠금을 얻는다. 보다 효율적인 방법은 Guava lib의 ComputableConcurrentHashMap과 같은 것을 사용하는 것입니다.

+0

감사합니다. 효율성은 현재 문제가 아닙니다. 해결책이 내 용도로 제공됩니다. 다시 한 번 감사드립니다. –

1

동기화 된 메커니즘은 좋지만, java.util.concurrent.locks 패키지의 Lock 인터페이스를 살펴보고 싶을 수도 있습니다. 이들은 사용하기가 더 장황하지만, 시도 또는 실패와 같은 일을하거나 시간 초과로 획득하려고 시도 할 수 있기 때문에 더 큰 유연성을 허용합니다.

관련 문제