ConcurrentSkipListMap — 확장 가능한 동시성 정렬 맵
ConcurrentSkipListMap — 확장 가능한 동시성 정렬 맵
ConcurrentSkipListMap<K,V>는 SkipList를 기반으로 한 확장 가능한(scalable) 동시성 ConcurrentNavigableMap 구현이에요. 정렬된 키 순서를 유지하면서도 여러 스레드가 안전하게 동시 접근해야 할 때 사용해요.
본문
개념 이해하기
ConcurrentSkipListMap은 키의 자연 순서 또는 생성 시 제공한 Comparator에 따라 정렬되는 확장 가능한 ConcurrentNavigableMap 구현이에요.
public class ConcurrentSkipListMap<K,V>
extends AbstractMap<K,V>
implements ConcurrentNavigableMap<K,V>, Cloneable, Serializable
containsKey,get,put,remove및 그 변형에 대해 평균 log(n) 시간 비용을 제공해요. 삽입·제거·업데이트·접근이 여러 스레드에서 안전하게 동시에 실행돼요.- iterator와 spliterator는 약하게 일관적이에요.
- 오름차순 키 정렬 뷰와 그 iterator가 내림차순보다 빠르다는 점을 기억하세요.
- 이 클래스와 뷰가 반환하는
Map.Entry쌍은 생성 시점의 매핑 스냅샷이며,Entry.setValue를 지원하지 않아요. (관련 맵 매핑 변경은put,putIfAbsent,replace로 가능) putAll,equals,toArray,containsValue,clear같은 일괄 연산은 원자적으로 수행된다는 보장이 없어요.- 일부
null반환 값을 "요소 없음"과 구별할 수 없으므로null키나 값은 허용하지 않아요.
생성자
public ConcurrentSkipListMap() — 키의 자연 순서로 정렬된 새 빈 맵을 만들어요.
public ConcurrentSkipListMap(Comparator<? super K> comparator) — 지정된 comparator로 정렬하는 새 빈 맵을 만들어요. null이면 자연 순서.
public ConcurrentSkipListMap(Map<? extends K,? extends V> m) — 주어진 맵과 같은 매핑을 가진 새 맵을 만들어요.
ClassCastException(비교 불가),NullPointerException
public ConcurrentSkipListMap(SortedMap<K,? extends V> m) — 주어진 정렬 맵과 같은 매핑·정렬을 가진 새 맵을 만들어요.
NullPointerException
public ConcurrentSkipListMap<K,V> clone() — 이 맵의 얕은 복사본을 반환해요 (키·값 자체는 복제되지 않음).
기본 맵 연산
public boolean containsKey(Object key) — 키에 대한 매핑이 있으면 true.
ClassCastException,NullPointerException
public V get(Object key) — 키에 매핑된 값 또는 null.
ClassCastException,NullPointerException
public V getOrDefault(Object key, V defaultValue) — 키 매핑 값 또는 기본 값. (JDK 1.8+)
public V put(K key, V value) — 키에 값을 매핑해요. 이전 값 또는 null을 반환.
ClassCastException,NullPointerException
public V remove(Object key) — 키의 매핑을 제거해요. 이전 값 또는 null.
public boolean containsValue(Object value) — 하나 이상의 키가 값에 매핑되면 true. 맵 크기에 선형 시간이 필요해요.
NullPointerException
public int size() / public boolean isEmpty() / public void clear() — 표준 맵 연산들.
compute·merge 계열 (JDK 1.8+)
public V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction) — 키가 값과 연관되지 않았다면 함수로 값을 계산해 null이 아니면 넣어요. 함수가 원자적으로 정확히 한 번 적용되는 건 보장되지 않아요.
NullPointerException(키 또는 함수가null)
public V computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) — 키의 값이 있으면 새 매핑을 계산해요. 함수가 원자적으로 한 번 적용되는 건 보장되지 않아요.
public V compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) — 키와 현재 값으로 매핑을 계산해요.
public V merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction) — 키가 값과 연관되지 않았다면 주어진 값과 연관, 그렇지 않으면 함수 결과로 교체하거나 null이면 제거해요.
원자적 조건 연산 (ConcurrentMap)
public V putIfAbsent(K key, V value) — 키가 값과 연관되지 않았다면 주어진 값과 연관시켜요. 원자적.
ClassCastException,NullPointerException
public boolean remove(Object key, Object value) — 키가 값에 매핑돼 있을 때만 제거해요. 원자적.
public boolean replace(K key, V oldValue, V newValue) — 키가 기대 값에 매핑돼 있을 때만 교체해요. 원자적.
public V replace(K key, V value) — 키가 어떤 값에 매핑돼 있을 때만 교체해요. 원자적.
뷰 메서드
public NavigableSet<K> keySet() — 키의 NavigableSet 뷰. iterator는 오름차순. spliterator는 CONCURRENT, NONNULL, SORTED, ORDERED 보고. 요소 제거를 지원하되 add/addAll은 지원하지 않아요. navigableKeySet()과 동등.
public NavigableSet<K> navigableKeySet() — 오름차순 키 NavigableSet 뷰.
public Collection<V> values() — 값의 Collection 뷰. iterator는 대응 키의 오름차순으로 값을 반환해요.
public Set<Map.Entry<K,V>> entrySet() — 매핑의 Set 뷰. iterator는 오름차순 키 순서로 엔트리를 반환해요. 순회되는 Map.Entry는 setValue를 지원하지 않아요.
public ConcurrentNavigableMap<K,V> descendingMap() — 매핑의 역순 뷰.
public NavigableSet<K> descendingKeySet() — 키의 역순 NavigableSet 뷰.
정렬 연산 (SortedMap)
public Comparator<? super K> comparator() — 정렬에 쓰는 comparator 또는 자연 순서면 null.
public K firstKey() — 첫(가장 낮은) 키. 비어 있으면 NoSuchElementException.
public K lastKey() — 마지막(가장 높은) 키. 비어 있으면 NoSuchElementException.
public V putFirst(K k, V v) / public V putLast(K k, V v) — 정렬 기반이라 명시적 위치를 지원하지 않으므로 항상 UnsupportedOperationException을 던져요. (JDK 21+)
엔트리·키 내비게이션 (NavigableMap)
public Map.Entry<K,V> lowerEntry(K key) — 키보다 엄격히 작은 가장 큰 키의 엔트리, 없으면 null. 반환 엔트리는 setValue 미지원.
public K lowerKey(K key) — 키보다 엄격히 작은 가장 큰 키.
public Map.Entry<K,V> floorEntry(K key) / public K floorKey(K key) — 키보다 작거나 같은 가장 큰 키 (엔트리/키).
public Map.Entry<K,V> ceilingEntry(K key) / public K ceilingKey(K key) — 키보다 크거나 같은 가장 작은 키.
public Map.Entry<K,V> higherEntry(K key) / public K higherKey(K key) — 키보다 엄격히 큰 가장 작은 키.
public Map.Entry<K,V> firstEntry() — 가장 작은 키의 엔트리, 비어 있으면 null.
public Map.Entry<K,V> lastEntry() — 가장 큰 키의 엔트리, 비어 있으면 null.
public Map.Entry<K,V> pollFirstEntry() — 가장 작은 키의 엔트리를 제거·반환, 비어 있으면 null.
public Map.Entry<K,V> pollLastEntry() — 가장 큰 키의 엔트리를 제거·반환, 비어 있으면 null.
범위 뷰
subMap/headMap/tailMap의 include/exclude 및 단일 인자 변형들이 있어요. 범위 밖 키 삽입 시 IllegalArgumentException. 각 변형의 예외(ClassCastException, NullPointerException, IllegalArgumentException)는 관련 문서 참고.