ConcurrentSkipListMap — 확장 가능한 동시성 정렬 맵

ConcurrentSkipListMap — 확장 가능한 동시성 정렬 맵

ConcurrentSkipListMap<K,V>SkipList를 기반으로 한 확장 가능한(scalable) 동시성 ConcurrentNavigableMap 구현이에요. 정렬된 키 순서를 유지하면서도 여러 스레드가 안전하게 동시 접근해야 할 때 사용해요.

출처: Java API Reference

본문

개념 이해하기

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.EntrysetValue를 지원하지 않아요.

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)는 관련 문서 참고.

더 알아보기 (Learn more)