Java Adv 20 - 자바 동시성 컬렉션 - 2
in Programming Language on Java
동시성 컬렉션(Concurrent Collections)
자바 1.5부터 멀티스레드 환경에서 성능을 최적화하면서 동시성을 지원하는 여러 가지 컬렉션들이 추가되었다. 이 컬렉션들은 java.util.concurrent 패키지에 포함되어 있으며, 스레드 안전(Thread Safe)하고 성능을 고려한 다양한 동기화 기법을 적용하여, 멀티스레드 환경에서의 효율적인 데이터 처리와 동시 접근을 지원한다.
동시성 컬렉션의 특징
기존의 java.util 패키지에서 제공하는 컬렉션들은 기본적으로 스레드 안전하지 않다. 이러한 컬렉션들(ArrayList, HashMap 등)은 여러 스레드가 동시에 접근할 경우 데이터 불일치나 경쟁 상태(race condition)를 일으킬 수 있다. 반면, 동시성 컬렉션들은 멀티스레드 환경에서 동기화 문제를 해결하면서도 성능 최적화를 고려하여 설계되었다. 동시성 컬렉션은 정교한 잠금 메커니즘을 사용한다. 예를 들어, Lock, CAS(Compare-And-Swap), 분할 잠금(segment lock) 등을 활용하여 각 스레드가 경쟁적으로 데이터를 수정하지 않도록 하고, 여러 스레드가 동시에 안전하게 접근할 수 있도록 지원한다.
동시성 컬렉션 클래스
자바는 여러 종류의 동시성 컬렉션을 제공하며, 이를 통해 다양한 자료 구조의 동기화 문제를 해결할 수 있다. 아래는 자주 사용되는 동시성 컬렉션 클래스들이다
1. List
- **
CopyOnWriteArrayList**ArrayList의 대안으로, 내부 배열을 복사하여 수정하는 방식으로 동기화를 처리한다. - 읽기 작업이 많고 쓰기 작업이 적은 경우에 적합하다.
- 멀티스레드 환경에서 쓰기 작업이 발생할 때마다 배열이 복사되므로 쓰기 작업의 성능이 떨어질 수 있다.
2. Set
- CopyOnWriteArraySet
HashSet의 대안으로, 내부적으로CopyOnWriteArrayList를 사용하여 동기화를 처리한다.- 쓰기 작업이 많은 환경에서는 성능 저하가 있을 수 있지만, 읽기 작업이 많은 환경에서 유리하다.
- ConcurrentSkipListSet
TreeSet의 대안으로, 정렬된 순서를 유지하면서 스레드 안전성을 보장한다.Comparator를 사용하여 정렬 순서를 설정할 수 있다.
3. Map
- ConcurrentHashMap
HashMap의 대안으로, 내부적으로 분할 잠금(Segment Lock)을 사용하여 성능을 최적화한다. 여러 스레드가 동시에 다른 세그먼트에 접근할 수 있어 동시성 처리 성능이 뛰어나다.
- ConcurrentSkipListMap
TreeMap의 대안으로, 정렬된 순서를 유지하면서 스레드 안전성을 보장한다.Comparator를 사용하여 정렬 순서를 설정할 수 있다.
4. Queue
- ConcurrentLinkedQueue비차단(non-blocking) 큐로, CAS(Compare-And-Swap) 기법을 사용하여 스레드 안전성을 보장한다. 여러 스레드가 동시에 큐에 접근할 수 있다.
5. Deque
- ConcurrentLinkedDeque비차단(non-blocking) 덱(Deque)으로, 양쪽 끝에서 삽입 및 삭제가 가능하며, CAS 기법을 사용해 동기화가 이루어진다. 멀티스레드 환경에서 효율적으로 사용된다.
BlockingQueue
BlockingQueue는 데이터를 삽입하거나 제거할 때 차단(blocking) 기능을 제공하는 큐로, 주로 생산자-소비자 패턴에서 사용된다. 여러 종류의 블로킹 큐가 제공되며, 각 큐는 고유의 특징을 가지고 있다.
ArrayBlockingQueue
고정 크기의 블로킹 큐로, 큐가 가득 찼을 때 삽입을 차단하고, 큐가 비었을 때 제거를 차단한다. 공정(fair) 모드를 지원하며, 이를 통해 큐에 접근하는 스레드의 순서를 보장할 수 있다. 그러나 공정 모드를 사용하면 성능 저하가 발생할 수 있다.
LinkedBlockingQueue
크기가 고정되거나 무한인 블로킹 큐로, 큐가 가득 차면 삽입을 차단하고, 큐가 비면 제거를 차단한다. 큐의 크기가 동적으로 조정될 수 있어 유연하게 사용될 수 있다.
PriorityBlockingQueue
우선순위가 높은 요소를 먼저 처리하는 블로킹 큐이다. 우선순위는 자연 순서나 사용자가 제공하는
Comparator에 의해 결정된다. 데이터가 삽입된 순서와는 상관없이 우선순위가 높은 요소가 먼저 처리된다.SynchronousQueue
데이터 저장소가 없는 블로킹 큐로, 생산자가 데이터를 삽입하면 소비자가 데이터를 받을 때까지 대기한다. 이 큐는 직접적인 핸드오프(hand-off) 메커니즘을 제공하여 생산자와 소비자가 데이터를 직접 주고받을 수 있게 한다.
DelayQueue
요소가 지정된 시간만큼 지연된 후에야 소비될 수 있는 블로킹 큐이다. 시간 지연이 필요한 작업을 처리하는 데 유용하다. 주로 스케줄링 작업이나 지연된 작업을 처리할 때 사용된다.
동시성 컬렉션의 장점과 단점
장점
- 성능 최적화:
ConcurrentHashMap,CopyOnWriteArrayList와 같은 컬렉션은 동기화 기법을 정교하게 적용하여 멀티스레드 환경에서 성능을 최적화한다. - 유연한 동기화:
java.util.concurrent패키지의 컬렉션들은 특정 메서드에만 동기화를 적용하거나, 잠금 범위를 세밀하게 조정하는 등의 유연한 동기화 전략을 제공한다. - 스레드 안전: 멀티스레드 환경에서 데이터를 안전하게 처리할 수 있어, 동시 접근 시 발생할 수 있는 데이터 불일치나 경쟁 상태를 방지할 수 있다.
단점
- 복잡한 구현: 동시성 컬렉션의 내부 구현은 복잡하고 고급 동기화 기법을 사용하므로, 이를 잘못 사용하면 성능이 저하될 수 있다.
- 메모리 소비: 일부 동시성 컬렉션은 추가적인 메모리 오버헤드를 발생시킬 수 있다. 예를 들어,
CopyOnWriteArrayList는 매번 데이터를 복사하므로 메모리 사용량이 증가할 수 있다. - 성능 저하: 동시성 컬렉션은 비록 멀티스레드 환경에서 안전하지만, 적절한 상황에서 사용되지 않으면 불필요한 동기화로 인해 성능 저하가 발생할 수 있다.
프록시 패턴을 이용하여 모든 객체에
Reference
김영한님의 자바 강의
https://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html