반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 |
Tags
- 정규식
- 테이블
- json
- CMD
- 자바
- 인텔리제이
- Eclipse
- CSS
- windows
- 배열
- string
- Button
- Array
- ArrayList
- Visual Studio Code
- IntelliJ
- html
- Java
- list
- 자바스크립트
- js
- date
- input
- javascript
- 이탈리아
- Maven
- table
- 문자열
- 이클립스
- vscode
Archives
- Today
- Total
어제 오늘 내일
[Java] Collections.synchronizedCollection()으로 아무 컬렉션이나 스레드 안전하게 본문
멀티스레드 환경에서 여러 스레드가 동시에 같은 컬렉션을 수정하면 데이터 불일치나 ConcurrentModificationException이 발생할 수 있습니다.
이때 Collections.synchronizedCollection()
으로 컬렉션을 감싸면 메서드 호출(add/remove 등)을 자동 동기화해 안전하게 사용할 수 있습니다.
이 메서드는 List
, Set
, Queue
등 임의의 컬렉션을 스레드 안전(Thread-Safe)하게 감싸는 범용 래퍼입니다.
1. 기본 사용법
import java.util.*;
public class SyncCollectionExample1 {
public static void main(String[] args) {
Collection<String> bag = new ArrayDeque<>(); // 어떤 컬렉션이든 가능
Collection<String> syncBag = Collections.synchronizedCollection(bag);
syncBag.add("apple");
syncBag.add("banana");
syncBag.add("cherry");
System.out.println(syncBag);
}
}
👉 ArrayDeque
처럼 전용 동기화 래퍼가 없는 컬렉션도 한 줄로 스레드 안전하게 만들 수 있습니다.
2. 반복(iteration) 시 주의: 수동 동기화 필요
메서드 호출은 래퍼가 동기화해 주지만, 반복문은 직접 동기화 블록으로 감싸야 합니다.
import java.util.*;
public class SyncCollectionExample2 {
public static void main(String[] args) {
Collection<Integer> base = new ArrayDeque<>();
Collection<Integer> sync = Collections.synchronizedCollection(base);
sync.add(1); sync.add(2); sync.add(3);
// 안전한 반복
synchronized (sync) {
for (int n : sync) {
System.out.println(n);
}
}
}
}
왜? 반복 중에 다른 스레드가 구조를 바꾸면 일관성이 깨질 수 있기 때문입니다.
3. 어떤 때 유용한가?
- 전용 동기화 래퍼가 없는 컬렉션을 쓰는 경우
(예:ArrayDeque
, 특정 라이브러리 컬렉션 등) - 컬렉션 타입을 나중에 바꿀 수 있는 인터페이스 설계
→Collection<T>
로 노출하고 내부는 필요 시 동기화 래퍼로 교체 - 간단한 멀티스레드 상황에서 빠르게 안전성 확보
4. synchronizedList/Set/Map과의 관계
Collections.synchronizedList
,synchronizedSet
,synchronizedMap
은 해당 타입 전용 래퍼를 제공합니다.synchronizedCollection
은 가장 범용적이며, 리스트/셋/큐 등 아무 컬렉션이나 감쌀 수 있습니다.- 공통점: 메서드 자동 동기화, 반복 시
synchronized
블록 필요.
5. 동기화 래퍼 vs 동시성 컬렉션(Concurrent Collections)
어떤 것을 써야 할까요?
Collections.synchronized*
계열- 장점: 간단, 기존 컬렉션을 그대로 감쌈
- 단점: 전체 메서드에 공유 락 1개 → 경쟁이 많으면 병목 가능
- 동시성 컬렉션 (
ConcurrentHashMap
,CopyOnWriteArrayList
,ConcurrentLinkedQueue
등)- 장점: 경쟁이 많은 환경에서 더 나은 확장성/성능
- 단점: 동작 특성이 다름(스냅샷 일관성, 약한 일관성 등), 사용법 이해 필요
👉 읽기 많고 쓰기 적음: CopyOnWriteArrayList
👉 키-값 공유, 고경쟁: ConcurrentHashMap
👉 간단·저경쟁: synchronizedCollection
도 충분
6. 정리
Collections.synchronizedCollection(Collection<T> c)
→ 어떤 컬렉션이든 스레드 안전 래퍼로 감싸서 반환- 메서드 호출은 자동 동기화, 반복은
synchronized
블록으로 직접 보호 - 고경쟁/고성능이 필요하면 동시성 컬렉션을 고려
👉 전용 래퍼가 없는 컬렉션을 멀티스레드에서 써야 한다면 Collections.synchronizedCollection()
으로 간단히 안전하게!
반응형
'IT > Java' 카테고리의 다른 글
[Java] Collections.rotate() – 리스트를 간단히 회전시키는 방법 (0) | 2025.09.11 |
---|---|
[Java] Collections.disjoint() – 두 컬렉션이 겹치지 않는지 확인하기 (0) | 2025.09.10 |
[Java] Collections.synchronizedSet()으로 스레드 안전한 집합 만들기 (0) | 2025.09.09 |
[Java] Collections.synchronizedMap()으로 스레드 안전한 맵 만들기 (0) | 2025.09.09 |
[Java] Collections.synchronizedList()로 스레드 안전한 리스트 만들기 (0) | 2025.09.08 |
Comments