멀티스레드와 동시성

Ch11. 동시성 컬렉션 - 동시성 컬렉션

webmaster 2024. 9. 15. 16:02
728x90

자바 1.5부터 동시성에 대한 많은 혁신이 이루어졌다. 그중에 동시성을 위한 컬렉션도 있다. 여기서 말하는 동시성 컬렉션은 스레드 안전한 컬렉션을 뜻한다.

java.util.concurrent 패키지에는 고성능 멀티스레드 환경을 지원하는 다양한 동시성 컬렉션 클래스들을 제공한다. 예를 들어, ConcurrentHashMap , CopyOnWriteArrayList , BlockingQueue 등이 있다. 이 컬렉션들 은 더 정교한 잠금 메커니즘을 사용하여 동시 접근을 효율적으로 처리하며, 필요한 경우 일부 메서드에 대해서만 동기화를 적용하는 등 유연한 동기화 전략을 제공한다.

 

여기에 다양한 성능 최적화 기법들이 적용되어 있는데, synchronized , Lock ( ReentrantLock ), CAS , 분할 기술(segment lock) 다양한 방법을 섞어서 매우 정교한 동기화를 구현하면서 동시에 성능도 최적화했다. 각각의 최적화는 매우 어렵게 구현되어 있기 때문에, 자세한 구현을 이해하는것보다는,멀티스레드 환경에 필요한 시성 컬렉션을 선택해서 사용할 있으면 충분하다.

 

동시성 컬렉션 종류

  • List
    • CopyOnWriteArrayList: ArrayList의 대안
  • Set
    • CopyOnWriteArraySet:  HashSet의 대안
    • ConcurrentSkipListSet: TreeSet의 대안(정렬된 순서 유지, Comparator 사용 가능)
  • Map
    • ConcurrentHashMap: HashMap 대안
    • ConcurrentSkipListMap: TreeMap 대안(정렬된 순서 유지, Comparator 사용 가능)
  • Queue
    • ConcurrentLinkedQueue : 동시성 , 차단(non-blocking) 큐이다.
  • Deque
    • ConcurrentLinkedDeque : 동시성 데크, 차단(non-blocking) 큐이다.

참고로 LinkedHashSet , LinkedHashMap처럼 입력 순서를 유지하는 동시에 멀티스레드 환경에서 사용할 수 있 Set , Map 구현체는 제공하지 않는다. 필요하다면 Collections.synchronizedXxx()를 사용해야 한다.

 

스레드를 차단하는 블로킹 큐

  • BlockingQueue
    • ArrayBlockingQueue
      • 크기가 고정된 블로킹
      • 공정(fair) 모드를 사용할 있다. 공정(fair) 모드를 사용하면 성능이 저하될 있다.
    • LinkedBlockingQueue
      • 크기가 무한하거나 고정된 블로킹
    • PriorityBlockingQueue
      • 우선순위가 높은 요소를 먼저 처리하는 블로킹
    • SynchronousQueue
      • 데이터를 저장하지 않는 블로킹 큐로, 생산자가 데이터를 추가하면 소비자가 데이터를 받을 때까지 대기한다. 생산자-소비자 간의 직접적인 핸드오프(hand-off) 메커니즘을 제공한다. 쉽게 이야기해서 중간에 없이 생산자, 소비자가 직접 거래한다.
    • DelayQueue
      • 지연된 요소를 처리하는 블로킹 큐로, 요소는 지정된 지연 시간이 지난 후에야 소비될 있다. 시간이 지난 작업을 처리해야 하는 스케줄링 작업에 사용된다.

코드 예시

실행 코드 - List 예시
실행 결과

  • CopyOnWriteArrayList은 ArrayList의 대안이다.

실행 코드 - Set 예시
실행 결과

  • CopyOnWriteArraySet은 HashSet의 대안이다.
  • ConcurrentSkipListSet은 TreeSet의 대안이다. 데이터의 정렬 순서를 유지한다. Comparator 사용 가능

실행 코드 - Map 예시
실행 결과

  • ConcurrentHashMap은 HashMap의 대안이다.
  • ConcurrentSkipListMap은 TreeMap의 대안이다. 데이터의 정렬 순서를 유지한다. Comparator 사용 가능

 

자바가 제공하는 동시성 컬렉션은 멀티스레드 상황에 최적의 성능을 낼 수 있도록 다양한 최적화 기법이 적용되어 있다. 따라서 Collections.synchronizedXxx를 사용하는 것보다 더 좋은 성능을 제공한다.


당연한 이야기지만 동시성은 결국 성능과 트레이드 오프가 있다. 따라서 단일 스레드가 컬렉션을 사용하는 경우에는 동 시성 컬렉션이 아닌 일반 컬렉션을 사용해야 한다. 반대로 멀티스레드 상황에서 일반 컬렉션을 사용하면 정말 해결하기 어려운 버그를 만날 수 있다. 세상에서 가장 해결하기 어려운 버그가 멀티스레드로 인해 발생한 버그이다.

 

이러한 이유로 멀티스레드 환경에서는 동시성 컬렉션을 적절히 활용해서 버그를 예방하고 성능을 최적화하는 것이 중요하다. 동시성 컬렉션을 사용하면 코드의 안정성과 효율성을 높일 있으며, 예상치 못한 동시성 문제도 방지할 있다.

728x90