2017-01-07 1 views
0

JDK1.6에서 ConcurrentHashMap의 소스 코드를 읽을 때 put 메서드가 값을 검사했기 때문에 readValueUnderLock(e)에 연결할 수없는 것으로 나타났습니다. 값이 null 인 경우 NullPointerException을 가져와야합니다. 그래서 뭔가 잘못 될 수 있다고 생각하지만 그것이 무엇인지 모르겠습니다. 누군가가 나를 대답 할 수 있으면 감사 할께! 여기readValueUnderLock (e)가 ConcurrentHashMap의 get 메소드에 존재하는 이유는 무엇입니까?

일부 소스 코드 :

V get(Object key, int hash) { 
    if (count != 0) { // read-volatile 
     HashEntry<K,V> e = getFirst(hash); 
     while (e != null) { 
      if (e.hash == hash && key.equals(e.key)) { 
       V v = e.value; 
       if (v != null) 
        return v; 
       return readValueUnderLock(e); // recheck 
      } 
      e = e.next; 
     } 
    } 
    return null; 
} 

V readValueUnderLock(HashEntry<K,V> e) { 
    lock(); 
    try { 
     return e.value; 
    } finally { 
     unlock(); 
    } 
} 

public V put(K key, V value) { 
    if (value == null) 
     throw new NullPointerException(); 
    int hash = hash(key.hashCode()); 
    return segmentFor(hash).put(key, hash, value, false); 
} 

답변

1

V 단지 Entry.value의 스냅 샷입니다. 엔트리는 아직 완전하게 구축되지 않았을 가능성이있어 (이전의 Java Memory Model로 더블 체크 락의 문제를 고려해), null 일 가능성이 있습니다. 이것은 극단적 인 경우 일 뿐이지 만 JRE는이 기능이 제대로 작동하는지 확인해야하므로 readValueUnderLock이 있습니다.

추신 : 시간을 따라하는 것이 좋습니다. Java는 진화하고 있으며 Java 9는 몇 달 안에 출시 될 예정입니다. 코드베이스에 엄청난 변화가있었습니다. 쓸모없는 지식으로 머리를 가득 채우는 것은 좋은 생각이 아닙니다.

+0

'ConcurrentHashMap'에 관해서는 쓸모없는 것이 없습니다. – chrylis

+1

예, 쓸모 없지만 내부 구현이 많이 바뀌 었습니다. Java 8에서 CHM 내부에서'HashEntry' 또는'Segment'를 찾을 수 없습니다. Java 6의 CHM 내부에 대한 지식은 더 이상 사용되지 않으며 사용 된 해킹은 나중에 자바 버전에서 필요하지 않거나 정확하지 않을 수 있습니다. 클라이언트가 Java6 만 필요하다고 단단히 믿고 그것을 업그레이드하지 않기로 결정한 경우 필요합니다. 이는 일반적인 경우가 아닙니다. – glee8e

+0

나는'double-check'을 안다 - 싱글 톤 패턴의 구현 중 하나. 키워드'volatile'이 없으면 인스턴스는 null이 아니며 올바른 값이 아닙니다 (아직 완전히 구성되지 않았습니다). 'readValueUnderLock'은 휘발성과 같은 역할을한다는 것을 의미합니다 (JDK1.6 이후의 효과)? –

관련 문제