CopyOnWriteArraySet — 쓰기 시 복사 동시성 셋

CopyOnWriteArraySet — 쓰기 시 복사 동시성 셋

CopyOnWriteArraySet<E>는 모든 연산에 내부 CopyOnWriteArrayList를 사용하는 Set이에요. 읽기가 압도적으로 많고 변경이 드문 작은 셋에 적합한 스레드 안전한 구현이에요.

출처: Java API Reference

본문

개념 이해하기

CopyOnWriteArraySet은 모든 연산에 내부 CopyOnWriteArrayList를 사용하는 Set이에요. 그래서 같은 기본 속성을 공유해요.

public class CopyOnWriteArraySet<E>
extends AbstractSet<E>
implements Serializable
  • 셋 크기가 일반적으로 작고, 읽기 전용 연산이 변경 연산을 압도적으로 많이 앞서며, 순회 중 스레드 간 간섭을 막아야 하는 애플리케이션에 가장 적합해요.
  • 스레드 안전해요.
  • 변경 연산(add, set, remove 등)은 비싸요 — 보통 전체 내부 배열을 복사하기 때문이에요.
  • iterator는 변경적 remove 연산을 지원하지 않아요.
  • iterator를 통한 순회는 빠르고 다른 스레드의 간섭을 만날 수 없어요 — iterator는 생성 시점의 변하지 않는 배열 스냅샷에 의존해요.

활용 예

class Handler { void handle() { ... } }

class X {
    private final CopyOnWriteArraySet<Handler> handlers
        = new CopyOnWriteArraySet<>();
    public void addHandler(Handler h) { handlers.add(h); }

    private long internalState;
    private synchronized void changeState() { internalState = ...; }

    public void update() {
        changeState();
        for (Handler handler : handlers)
            handler.handle();
    }
}

생성자

public CopyOnWriteArraySet() — 빈 셋을 만들어요.

public CopyOnWriteArraySet(Collection<? extends E> c) — 주어진 컬렉션의 모든 요소를 담은 셋을 만들어요.

  • NullPointerException

기본 연산

public int size() / public boolean isEmpty() — 표준.

public boolean contains(Object o)Objects.equals(o, e)인 요소가 있으면 true.

public boolean add(E e) — 같은 요소가 없으면 추가해요. 이미 있으면 셋을 바꾸지 않고 false.

public boolean remove(Object o) — 요소가 있으면 제거해요. 제거됐으면 true.

public void clear() — 모든 요소를 제거해요.

일괄 연산

public boolean containsAll(Collection<?> c) — 모든 요소 포함 시 true. 컬렉션이 셋이면 부분집합 여부. NullPointerException.

public boolean addAll(Collection<? extends E> c) — 아직 없는 요소만 추가해요(합집합 효과). NullPointerException.

public boolean removeAll(Collection<?> c) — 포함된 요소를 모두 제거해요(비대칭 차집합 효과).

public boolean retainAll(Collection<?> c) — 포함된 요소만 남겨요(교집합 효과).

public boolean removeIf(Predicate<? super E> filter) / public void forEach(Consumer<? super E> action) — 표준 컬렉션 연산.

public boolean equals(Object o) — 같은 Set이고 같은 요소면 true.

iterator/spliterator

public Iterator<E> iterator()요소가 추가된 순서대로 요소를 반환하는 iterator. 생성 시점 스냅샷이며 순회 중 동기화가 필요 없고, remove를 지원하지 않아요.

public Spliterator<E> spliterator() — 추가된 순서대로 IMMUTABLE, DISTINCT, SIZED, SUBSIZED를 보고하는 spliterator. 생성 시점 스냅샷. (JDK 1.8+)

더 알아보기 (Learn more)