Concurrent Collection이란 (병렬 컬렉션)
Concurrent(병렬/동시성)이란 단어에서 알 수 있듯이 Synchronized 컬렉션과 달리 여러 스레드가 동시에 컬렉션에 접근할 수 있다. (Thread-safe 하다)
Synchronized 컬렉션은 하나의 스레드가 접근 시 다른 스레드는 아예 접근이 불가능하지만, Concurrent 컬렉션은 보관하고 있는 데이터를 여러 부분으로 나눠서 Lock을 걸어 다른 부분에 접근 중이라면 여러 스레드가 동시 접근이 가능하다.
여러 스레드가 한 번에 접근 가능하기 때문에 스레드 대기 시간을 줄여주며, Synchronized 컬렉션보다 성능이 높다.
하나 이상의 스레드가 병렬적으로 read, write 연산을 할 수 있다.
종류
java.util.concurrent 패키지에서 제공하는 Concurrent...로 시작하는 컬렉션이다.
CopyOnWriteArrayList
모든 쓰기 작업 시 원본 배열에 있는 요소를 복사하여 새로운 임시 배열을 만들고, 이 임시 배열에 쓰기 동작을 수행한 후 원본 배열을 갱신한다.
따라서 이러한 작업 과정에서 동시성을 보장하기 위하여 쓰기 작업(add) 시 Lock을 걸게 된다.
하지만 이러한 Lock은 쓰기 작업의 성능을 저하시킨다. Lock을 획득하는 동안에는 다른 스레드는 해당 List에 접근할 수 없기 때문에 쓰기 작업이 빈번하게 발생하는 경우 성능에 문제가 발생할 수 있다.
ConcurrentHashMap
검색 및 업데이트에 대한 높은 동시성을 지원하는 HashMap의 향상된 기능으로 JDK 1.5에 도입되었다.
Thread-safe 하며, 멀티스레드 환경에서 복잡한 문제없이 단일 객체로 작동할 수 있다.
기본적으로 16개의 버킷을 가지며, 각 버킷마다 자체적으로 Lock을 가지고 있기 때문에 총 16개의 Lock을 가지고 있다. 따라서 별도의 버킷에 있는 key에 접근하는 스레드는 동시에 접근이 가능하다. (Lock Striping이라는 동기화 기법을 사용한다.)
위 그림을 보면 같은 버킷의 key에 접근하려는 스레드들은 그중 하나만 접근할 수 있도록 한다. 다른 버킷의 key에 접근하려는 스레드들은 접근이 가능하다. 따라서 Lock Striping 방식을 사용한 현재 그림에선 6개 중 3개의 스레드가 동시에 데이터 구조에서 작업을 할 수 있다.
ConcurrentLinkedQueue
다른 Concurrent 컬렉션과 마찬가지로 Thread-Safe 한 구조를 가지고 있다.
non-blocking, lock-free queue라는 특징을 가지고 있으며 Queue가 비었을 경우에 null을 리턴하는 특징이 있다.
사용방법은 기존 LinkedList와 유사하여 offer(), poll(), peek()등의 메서드를 지원한다.
LinkedBlockingQueue
Blocking Queue가 Linked 노드로 연결된 구조이며, Queue에서 꺼내갈 자원이 없을 경우에 해당 스레드는 wait 상태에 들어가게 된다.
LinkedBlockngQueue 내에 있는 데이터를 가져오기 위해 poll()과 take() 메서드를 제공한다. 이 두메소드의 차이점은 queue가 비어있을 때, poll()은 null을 리턴하거나 Timeout 을 설정할 수 있는 반면에, take()는 꺼낼 수 있는 원소가 있을 때까지 기다린다.
참조
https://dogcowking.tistory.com/279
'멋진 개발자 > Java & Spring' 카테고리의 다른 글
개발자 성장 기록 46 - Java의 접근제어자 (0) | 2024.04.12 |
---|---|
개발자 성장 기록 45 - String, StringBuffer, StringBuilder (0) | 2024.04.09 |
개발자 성장 기록 43 - Thread Pool (1) | 2024.04.07 |
개발자 성장 기록 42 - Java 직렬화 (Serialization) (0) | 2024.04.06 |
개발자 취준 기록 39 - Java 버전 별 차이 (0) | 2024.04.04 |