2016-11-15 1 views
3

키가 ConcurrentHashMap에 존재하지 않는 경우에만 코드를 실행하고 코드 결과를 컬렉션에 저장합니까?Java 7의 ComputeIfAbsent와 같습니다.

Android 용으로 개발 중이므로 Java 8 기능을 사용할 수 없습니다.

또한 필자는 그렇게 할 필요가 없으며 그렇게하기 위해 컬렉션의 원자 적 연산을 중단하고 싶지 않은 경우 장기 실행을 피하고 싶습니다.

+2

작동하지 않는'if (! map.containsKey (key)) '에 대해 뭔가 있습니까? – Zircon

+1

@Zircon computeIfAbsent는 함수의 결과를 해당 키의 새 값으로 원자 적으로 삽입합니다. 따라서 추가 작업없이 100 % 교체되지는 않습니다. –

+0

@SotiriosDelimanolis 그는 분명히 그것이 원자적일 것이라고 말합니다. 따라서 해당 사항이 없습니다. 동일한 것을 작성할 수는 있지만 명시 적 세마포어로 자체 잠금을 수행해야합니다. –

답변

-1

아니요. 맵을 작동시키는 방법은지도 위에 자신 만의 잠금 기능을 사용하는 것입니다.

4

가 더 정확한 상응 없지만, 일반적인 접근 방식은이 같은 것입니다 :

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과 본질적으로 동일한 동작이지만 많은 추가 구성 옵션이 있습니다.

관련 문제