멀티스레드 환경에서 데이터 일관성과 충돌 방지는 반드시 고려해야 할 중요한 주제이다.
동기화(synchronization)와 원자적 연산(atomic operation)은 모두 이를 다루는 방법이지만, 그 목적과 동작 방식이 다르다.
동기화 (Synchronization)
- 공유 자원(변수, 객체, 컬렉션 등)에 여러 스레드가 동시 접근할 때 충돌을 막기 위한 보장 수단
- Java에서는 synchronized 키워드 또는 Lock 인터페이스를 통해 구현
✅ 예시
class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
}
이 코드에서는 increment() 메서드 전체가 임계 구역(critical section)으로 보호되어, 여러 스레드가 한 번에 실행할 수 없다.
장점 vs 단점
- ✔️ 완전한 보호: 임계 구역 전체가 스레드 안전
- ❌ 병목 발생 가능: 전체 메서드 동기화 시, 동시 처리 성능 저하
원자적 연산 (Atomic Operation)
- 단일 연산 단위로, 중간 중단이나 간섭 없이 실행되는 연산
- Java에서는 AtomicInteger, AtomicReference, AtomicBoolean 등 java.util.concurrent.atomic 패키지 제공
✅ 예시
import java.util.concurrent.atomic.AtomicInteger;
AtomicInteger atomicCount = new AtomicInteger(0);
atomicCount.incrementAndGet(); // 원자적 증가
이 코드에서 incrementAndGet()은 읽기+증가+저장을 하나의 연산 단위로 보장한다.
장점 vs 단점
- Lock-free: synchronized 없이도 안전하게 동작
- 성능 우수: 자주 호출되어도 병목이 적다
- 복합 연산에는 부적합: compare-then-act 등 여러 단계일 경우에도 별도 처리 필요하다
동기화 vs 원자적 연산 비교
| 동기화 (synchronized / Lock) | 원자적 연산 (Atomic*) | |
| 보호 단위 | 임계 구역 (메서드/블록) | 하나의 변수 연산 |
| 성능 | 락 경합 시 잠금 발생 가능 | 비차단 → 스루풋 좋음 |
| 복합 연산 | increment() 같은 경우 모두 보호 가능 | 위험, CAS 실패 시 재시도 필요 |
| 구현 복잡도 | 간단하지만 과도 사용 시 성능 저하 | 단일 변수 연산에 적합 |
- 단순한 증가/읽기처럼 변수를 원자적으로 다루고 싶다면:
→ AtomicInteger, AtomicLong 추천
AtomicInteger counter = new AtomicInteger();
counter.incrementAndGet();
- 여러 변수를 같이 보호하거나 복잡한 로직이 있을 때는:
→ synchronized 또는 ReentrantLock 사용
synchronized(this) {
x += 1;
y += 2;
}
- Atomic 연산은 단일 변수에 대해서만 원자적이며, 여러 변수나 조건부 업데이트는 동기화 필요
- synchronized는 과도하게 사용 시 성능 병목 우려 → 임계 구역을 좁게 유지
| 개념 | 보호 단위 | 성능 | 적합 사례 |
| 동기화 | 여러 라인/메서드 | 락 경합 시 느림 | 복합 로직, 여러 공유 자원 |
| 원자적 연산 | 단일 변수 | Lock-free 빠름 | 증가, 플래그 변경 등 단순 작업 |
- 동기화(synchronized)는 복잡한 상태와 여러 작업 보호에 적합하지만 성능 부담이 있을 수 있다.
- Atomic*는 단일 변수의 안전한 증가/읽기를 고성능으로 처리할 수 있어 현대 Java에서 가장 널리 사용되는 기법이다.
반응형
'IT > JAVA' 카테고리의 다른 글
| ReentrantLock 락 제어 (0) | 2025.12.06 |
|---|---|
| Java 예외: RuntimeException (0) | 2025.12.06 |
| ConcurrentHashMap – 멀티스레드 환경에서 안전하게 Map 사용하기 (1) | 2025.07.24 |
| Java String 클래스 (0) | 2025.04.15 |
| JMH (JMH 라이브러리를 활용한 Java 코드 성능테스트) (2) | 2025.04.11 |