2014-10-03 1 views
1

그래서 나는 lockMap 누군가가이 DCL의 전형적인 사례라고 언급 코드 검토 중에 ConcurrentHashMap더블 체크 잠금의 특별한 경우? 컴파일러는 이벤트를 재정렬 할 수 있기 때문에, 잠금이 가능성이 있기 때문

//Creation of locks 
Lock getLock(String key) { 
    Lock lock = lockMap.get(key); 
    if (lock == null) { 
     synchronized (lockMap) { 
      lock = lockMap.get(key); 
      if (lock == null) { 
       lock = new ReentrantLock(); 
       lockMap.put(key, lock); 
      } 
     } 
    } 

    return lock; 
} 

입니다이 코드를 지도에 삽입 될 때 아직 완전히 초기화되지 않은 경우 동일한 잠금을 요청하는 다음 스레드가 아직 완전히 초기화되지 않을 수 있습니다.

이제이 문제는이 문제가 멀티 스레드 응용 프로그램의 공통적 인 문제라는 것입니다.지도에서 무언가를 얻고 거기에 생성하고 추가하십시오.

  1. 이것은 실제로 DCL의 경우입니까?
  2. 그렇다면 어떻게 해결할 수 있습니까? 그래서 다시
  3. 하면 (우리가 사용하는 간단하고 바보 같은 방법은 잠금 풀을 만드는 것입니다 하나는 풀에서 추출 할 때 새가 삽입은)는 java8
+0

어떤 이벤트를 재주문 하시겠습니까? –

+0

왜 자물쇠를 두 번 쿼리합니까? 그리고 왜 지구상에 자물쇠가 있습니까? 모든 작업을 감각적으로 이해하기 위해서는 우선 사전에없는 자물쇠를 얻어야합니다. synchonized 메서드를 호출 한 다음 반환하기 전에 잠금을 잠급니다. – vidstige

+0

DCL [정의상] (http://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java)입니다. 그러나 @rolfl이 보여 주었 듯이, ConcurrentHashMap에'synchronize '할 필요는 없습니다. –

답변

2

사실에 고정되어 당신이 당신은 당신이 그들과 함께 무엇을하고 있는지 알고 가정하는 ConcurrentHashMap의이 .... 혼란에 잠금을 가지고 있지만, 더 나은 방법이 될 것이다 쓰기 :

Lock getLock(String key) { 
    Lock lock = lockMap.get(key); 
    if (lock == null) { 
     lock = new ReentrantLock(); 
     Lock race = lockMap.putIfAbsent(key, lock); 
     if (race != null) { 
      //there was a race, we lost. 
      lock = race; 
     } 
    } 
    return lock; 
} 

주에게 putIfAbsent() 원자 작업의 사용. 우리는 낙천적으로 새로운 Lock을 만들지 만, 만약 우리가 경기 조건을 잃어 버리면, 우리는 그것을 버리고 경주 승자 lock을 사용합니다.

+0

아무 것도 반환되지 않으므로 컴파일되지 않습니다. – vidstige

+0

초주세요 ... ....-) – rolfl

0

그래서 어쨌든 나는 늦은 응답에 대해 어떤 통보도받지 못했습니다. 결석하면 나는 넣을 거라 생각했는데, 아무 것도 (항상)하는 물체를 만드는 비용이 들었으므로 이것을 피하고 싶었습니다. 하지만이 솔루션을 사용할 수 있도록 비용은 최소한이라 생각합니다.

관련 문제