Thread-safe 컬렉션 완벽 이해하기
이전 글에서:
- synchronized
- volatile
- CAS
- AtomicInteger
를 배웠습니다.
그런데 실무에서는 숫자 하나만 공유하는 경우보다
List
Map
Set
같은 컬렉션을 여러 스레드가 동시에 사용하는 경우가 훨씬 많습니다.
문제는:
ArrayList
HashMap
HashSet
은 기본적으로
Thread-Safe 하지 않다.
입니다.
1. Thread-Safe란?
한 줄 정의.
여러 Thread가 동시에 접근해도
데이터가 깨지지 않는 것
2. ArrayList 예제
List<Integer> list =
new ArrayList<>();
Thread A
list.add(1);
Thread B
list.add(2);
동시에 실행.
3. 문제
ArrayList 내부.
elementData[size] = value;
size++;
실제로는 여러 단계.
4. Race Condition 발생
예:
size=5
Thread A
size 읽음
=5
Thread B
size 읽음
=5
Thread A
5번 인덱스 저장
Thread B
5번 인덱스 저장
결과
데이터 유실
가능.
5. HashMap도 위험
예:
Map<String, String> map =
new HashMap<>();
여러 Thread가
put()
동시 실행.
6. 실제 문제
예전 JDK 7 시절에는
무한 루프
까지 발생 가능.
지금도
데이터 손실
읽기 오류
가능.
7. 그래서 등장
Thread-safe 컬렉션.
대표적으로:
Vector
Collections.synchronizedList()
CopyOnWriteArrayList
ConcurrentHashMap
ConcurrentLinkedQueue
8. 첫 번째: Vector
옛날 Java.
Vector<String> vector =
new Vector<>();
9. 내부
사실상
public synchronized boolean add(...)
모든 메서드에
synchronized
적용.
10. 장점
안전.
11. 단점
느림.
모든 연산.
Lock
↓
실행
↓
Unlock
12. 그래서 실무
거의 안 씀.
13. Collections.synchronizedList
기존 List 감싸기.
List<String> list =
Collections.synchronizedList(
new ArrayList<>()
);
14. 내부 구조
synchronized(lock) {
}
로 감싸는 Wrapper.
15. 장점
간단.
16. 단점
Vector와 비슷.
모든 연산 Lock.
17. 반복문 문제
매우 중요.
for(String s : list) {
}
이건 안전할까?
18. 정답
아니다.
19. 공식 문서 권장
synchronized(list) {
Iterator<String> it =
list.iterator();
while(it.hasNext()) {
}
}
반복 전체를 Lock 해야 함.
20. 그래서 등장
CopyOnWriteArrayList.
21. CopyOnWriteArrayList란?
CopyOnWriteArrayList
이름 그대로.
쓰기 시 복사
22. 동작 방식
현재 배열.
[A B C]
add(D)
새 배열 생성.
[A B C D]
교체.
23. 장점
읽기 매우 빠름.
락 거의 없음.
24. 반복 중 수정 가능
for(...) {
}
중에도
list.add(...)
가능.
예외 안 남.
25. 단점
쓰기 비쌈.
추가할 때마다.
배열 복사
발생.
26. 언제 사용?
읽기 99%
쓰기 1%
환경.
예:
설정값
캐시 목록
리스너 목록
27. ConcurrentHashMap 등장
실무 최강.
ConcurrentHashMap
28. 왜 등장?
HashMap
빠름
하지만
Thread-Safe 아님
Hashtable
안전
하지만
너무 느림
중간 해법.
ConcurrentHashMap
29. 사용
Map<String, String> map =
new ConcurrentHashMap<>();
30. JDK 7 구조
예전에는.
Segment
기반.
Map
├─ Segment1
├─ Segment2
├─ Segment3
부분 Lock.
31. JDK 8 이후
현재 구조.
CAS
+
synchronized
조합.
32. 핵심 아이디어
전체 Lock 안 함.
필요한 Bucket만 Lock.
33. 장점
동시성 매우 좋음.
읽기 대부분 Lock 없음.
34. put()
경쟁 없으면
CAS
사용.
경쟁 심하면
synchronized
사용.
35. 그래서 빠름
HashTable보다 훨씬 빠름.
36. 실무 표준
멀티스레드 Map.
대부분
ConcurrentHashMap
사용.
37. ConcurrentLinkedQueue
큐 버전.
ConcurrentLinkedQueue
38. 특징
Lock-Free.
내부적으로
CAS
사용.
39. 사용
Queue<String> queue =
new ConcurrentLinkedQueue<>();
40. BlockingQueue
실무 중요.
대표:
LinkedBlockingQueue
ArrayBlockingQueue
41. 특징
데이터 없으면.
자동 대기
생산자-소비자 패턴.
Producer
↓
Queue
↓
Consumer
42. Thread-safe 컬렉션 비교
| 컬렉션 | Thread-Safe | 특징 |
| ArrayList | X | 일반 |
| HashMap | X | 일반 |
| Vector | O | 전체 Lock |
| synchronizedList | O | Wrapper |
| CopyOnWriteArrayList | O | 읽기 최적화 |
| ConcurrentHashMap | O | 실무 표준 |
| ConcurrentLinkedQueue | O | Lock-Free |
43. 실무 사용 빈도
압도적.
ConcurrentHashMap
그 다음.
CopyOnWriteArrayList
BlockingQueue
44. 면접 단골 질문
Q. HashMap은 Thread-Safe인가?
아니오
Q. Vector는 왜 잘 안 쓰나요?
모든 연산 Lock
Q. ConcurrentHashMap은 어떻게 빠른가요?
전체 Lock 안 함
CAS + 부분 Lock 사용
Q. CopyOnWriteArrayList 특징은?
읽기 빠름
쓰기 느림
Q. 실무에서 Thread-Safe Map은?
ConcurrentHashMap
45. 핵심 흐름 요약
ArrayList
HashMap
↓
멀티스레드 문제
↓
Vector
synchronizedList
↓
성능 문제
↓
CAS 기반
ConcurrentHashMap
CopyOnWriteArrayList
ConcurrentLinkedQueue
46. 가장 중요한 핵심 한 줄
Thread-safe 컬렉션은 여러 스레드가 동시에 접근해도 데이터 무결성을 보장하는 컬렉션이며, 실무에서는 ConcurrentHashMap이 가장 널리 사용된다.
47. 다음 글 예고
다음 글은:
ExecutorService
입니다.
여기서부터는:
new Thread(...)
를 실무에서 거의 안 쓰는 이유,
그리고
ThreadPool
↓
ExecutorService
↓
Future
↓
CompletableFuture
로 이어지는 현대 Java 동시성의 핵심 구조를 배우게 됩니다.
'language > java' 카테고리의 다른 글
| ThreadPool 구조 완벽 이해하기 (0) | 2026.06.01 |
|---|---|
| ExecutorService 완벽 이해하기 (0) | 2026.06.01 |
| Atomic 클래스 (AtomicInteger, AtomicLong 등) 완벽 이해하기 (0) | 2026.05.29 |
| CAS(Compare And Swap) 완벽 이해하기 (0) | 2026.05.29 |
| volatile 키워드 완벽 이해하기 (0) | 2026.05.29 |
댓글