키가 ConcurrentHashMap
에 존재하지 않는 경우에만 코드를 실행하고 코드 결과를 컬렉션에 저장합니까?Java 7의 ComputeIfAbsent와 같습니다.
Android 용으로 개발 중이므로 Java 8 기능을 사용할 수 없습니다.
또한 필자는 그렇게 할 필요가 없으며 그렇게하기 위해 컬렉션의 원자 적 연산을 중단하고 싶지 않은 경우 장기 실행을 피하고 싶습니다.
키가 ConcurrentHashMap
에 존재하지 않는 경우에만 코드를 실행하고 코드 결과를 컬렉션에 저장합니까?Java 7의 ComputeIfAbsent와 같습니다.
Android 용으로 개발 중이므로 Java 8 기능을 사용할 수 없습니다.
또한 필자는 그렇게 할 필요가 없으며 그렇게하기 위해 컬렉션의 원자 적 연산을 중단하고 싶지 않은 경우 장기 실행을 피하고 싶습니다.
아니요. 맵을 작동시키는 방법은지도 위에 자신 만의 잠금 기능을 사용하는 것입니다.
가 더 정확한 상응 없지만, 일반적인 접근 방식은이 같은 것입니다 :
ConcurrentMap<Key,Value> map = ...
Value computeIfAbsent(Key k) {
Value v = map.get(k);
if (v == null) {
Value vNew = new Value(...); // or whatever else you do to compute the value
v = (v = map.putIfAbsent(k, vNew)) == null ? vNew : v;
}
return v;
}
이 자바 8의 computeIfAbsent
호출이 거의 기능적으로 동일, 유일한 차이점은 때때로 당신이 Value
를 구성한다는 것와 다른 스레드가 먼저 그것을 넣기 때문에 결코 맵에 넣지 않는 객체. 잘못된 객체 또는 그와 같은 것을 반환하지 않습니다. 값의 구성에 부작용이있는 경우 함수가 Value
을 계속 반환하지만 은 *이 허용되지 않을 수 있습니다.
초기 get()
검사로 인해 putIfAbsent
에 대한 호출이 대부분 제거되므로 추가 인스턴스는 일반적으로 성능 문제가되지 않습니다. 일반적으로이 방법은 객체가 이미 존재할 때 불필요한 객체 잠금을 수행하기 때문에 상당히 일 수 있으며보다 computeIfAbsent
일 수 있습니다. 일부 개체가 심하게 경합하는 경우 로컬로 5 번으로 측정했습니다.
지도에 통합 된 컴퓨팅 동작이 정말로 필요한 경우 (정확히 하나의 스레드가 새 개체를 생성하도록 내부 잠금 장치가있는 상태에서) Guaya의 CacheBuilder
을 사용하여 LoadingCache
을 얻을 수 있습니다. Java 8의 CHM과 본질적으로 동일한 동작이지만 많은 추가 구성 옵션이 있습니다.
작동하지 않는'if (! map.containsKey (key)) '에 대해 뭔가 있습니까? – Zircon
@Zircon computeIfAbsent는 함수의 결과를 해당 키의 새 값으로 원자 적으로 삽입합니다. 따라서 추가 작업없이 100 % 교체되지는 않습니다. –
@SotiriosDelimanolis 그는 분명히 그것이 원자적일 것이라고 말합니다. 따라서 해당 사항이 없습니다. 동일한 것을 작성할 수는 있지만 명시 적 세마포어로 자체 잠금을 수행해야합니다. –