Oracle Java ConcurrentHashMap의 잘못된 구현?
Oracle의 Java 8 구현을 테스트 중입니다.
ConcurrentMap<String, String> concurrentMap = new ConcurrentHashMap<>();
String result = concurrentMap.computeIfAbsent("A", k -> "B");
System.out.println(result); // "B"
result = concurrentMap.putIfAbsent("AA", "BB");
System.out.println(result); // null
자바독은 그렇게 말합니다.
구현 요구 사항:
기본 구현은 이 맵에 대한 다음 단계와 같으며, 현재 값이 없으면 null을 반환합니다.
if (map.get(key) == null) { V newValue = mappingFunction.apply(key); if (newValue != null) return map.putIfAbsent(key, newValue); }
그러면 현재 값을 반환하거나 현재 없으면 null을 반환한다고 합니다.그래서 그것은 돌아올 것입니다.null
점을 하면,putIfAbsent
또한 돌아오고 있습니다.null
.
내가 여기서 뭘 놓쳤지요?
예ConcurrentMap.computeIfAbsent
실제 의도를 반영하지 않고 있습니다. 대부분의 경우 비폭력적인 행동으로 인한 실수일 가능성이 높습니다.putIfAbsent
구현이 문서화된 의도를 따르는 동안.이 문제는 JDK-8174087에서 보고되었으며 Java 9에서 해결되었습니다.
에 대한 계약은 다음과 같습니다.
구현 요구 사항:
기본 구현은 이 맵에 대한 다음 단계와 같으며, 현재 값이 없으면 null을 반환합니다.
if (map.get(key) == null) { V newValue = mappingFunction.apply(key); if (newValue != null) map.put(key, newValue); }
략생을 return
진술.하지만 분명히 말하지만,
반환:
지정된 키와 연결된 현재(기존 또는 계산된) 값 또는 계산된 값이 null인 경우 null
이것은 동시성 측면을 통합하려고 시도하는 문서이며, 다음의 비직관적인 행동에 속합니다.putIfAbsent
:
구현 요구 사항:
기본 구현은 이 맵에 대한 다음 단계와 같으며, 현재 값이 없으면 null을 반환합니다.
if (map.get(key) == null) { V newValue = mappingFunction.apply(key); if (newValue != null) return map.putIfAbsent(key, newValue); }
하지만 여전히 그것은 말합니다.
반환:
지정된 키와 연결된 현재(기존 또는 계산된) 값 또는 계산된 값이 null인 경우 null
그리고 문서화된 의도는 코드 예제보다 우선되어야 합니다.의 실제 구현은 문서화된 의도와 일치합니다.
@Override default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) { Objects.requireNonNull(mappingFunction); V v, newValue; return ((v = get(key)) == null && (newValue = mappingFunction.apply(key)) != null && (v = putIfAbsent(key, newValue)) == null) ? newValue : v; }
따라서 의 이행은 두 가지 모두의 문서화된 의도에 부합합니다.ConcurrentMap.computeIfAbsent
그리고.Map.computeIfAbsent
반환된 값과 관련하여 또한 다음과 같습니다.default
인터페이스에 의해 제공되는 구현.
전성을위해완,,default
의 구현
default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) { Objects.requireNonNull(mappingFunction); V v; if ((v = get(key)) == null) { V newValue; if ((newValue = mappingFunction.apply(key)) != null) { put(key, newValue); return newValue; } } return v; }
javadoc의 실제 코드:
if (map.get(key) == null) {
V newValue = mappingFunction.apply(key);
if (newValue != null)
map.put(key, newValue); // <-
}
}
보시다시피 없습니다.return
키워드를 입력합니다.
섹션 "return"에도 다음이 표시됩니다.
반환: 지정한 키와 연결된 현재(기존 또는 계산된) 값 또는 계산된 값이 null인 경우 null을 반환합니다.
언급URL : https://stackoverflow.com/questions/46272108/wrong-implementation-of-oracle-java-concurrenthashmap
'source' 카테고리의 다른 글
routerLink 속성을 조건부로 비활성화하려면 어떻게 해야 합니까? (0) | 2023.07.26 |
---|---|
레이저 기반 MVC 대 MVC의 단일 페이지 애플리케이션 4. (0) | 2023.07.26 |
어떤 매개 변수 세트가 사용되었습니까? (0) | 2023.07.26 |
두 문자열을 연결하기 위해 '+'를 사용하지 않을 이유가 있습니까? (0) | 2023.07.21 |
서비스 내에서 여러 서비스 또는 여러 리포지토리를 사용하고 있습니까? (0) | 2023.07.21 |