2026년 02월 14일

🔒 Java synchronized — 한 번에 하나만 들어오세요

Java Spring Boot
Cover Image

🔒 Java synchronized — 한 번에 하나만 들어오세요

한 줄 요약 : synchronized는 객체의 Monitor Lock을 사용해 임계 영역을 한 번에 하나의 스레드만 실행하게 만들어 Data Race를 방지하는 동기화 메커니즘이다.


⚠️ 왜 필요한가 — Data Race

count++ 한 줄이 실제로는 3단계 연산이다.

① count 읽기
② +1 계산
③ 다시 저장

멀티스레드 환경에서는 이 3단계 사이에 다른 스레드가 끼어든다.

Thread A : count 읽음 (0)
Thread B : count 읽음 (0)   ← A가 저장하기 전에 읽어버림
Thread A : 1 저장
Thread B : 1 저장           ← 2가 되어야 하는데 1이 됨

이것이 Data Race다. synchronized는 이 문제를 해결한다.


⚙️ 동작 원리 — Monitor Lock

Java의 모든 객체는 내부적으로 Monitor Lock을 하나씩 가진다.
synchronized 블록에 진입하려면 반드시 이 락을 먼저 획득해야 한다.

Thread A → 락 획득 → 임계 영역 실행
Thread B → 락 대기 중 ...
Thread A → 작업 완료 → 락 반환
Thread B → 락 획득 → 임계 영역 실행

한 번에 하나의 스레드만 임계 영역(Critical Section)에 진입할 수 있다.


✅ synchronized가 해결하는 2가지 문제

1. 상호 배제 (Mutual Exclusion)

동시 접근을 막아 Data Race를 제거한다.

public class Counter {
    private int count = 0;

    public synchronized void increment() {
        count++;  // 한 번에 하나의 스레드만 실행
    }
}

2. 메모리 가시성 (Memory Visibility)

synchronized 블록을 빠져나갈 때 변경된 값을 메인 메모리에 즉시 반영한다.
다른 스레드가 캐시가 아닌 최신 값을 읽도록 보장한다.


🛠️ 사용 방식 3가지

// 1. 메서드 전체 동기화
public synchronized void method() { ... }

// 2. 특정 블록만 동기화 (권장 — 임계 영역을 최소화)
public void method() {
    synchronized (this) {
        // 임계 영역
    }
}

// 3. 클래스 단위 동기화 (static 메서드)
public static synchronized void method() { ... }

💡 블록 동기화를 권장하는 이유 : 락을 잡고 있는 시간이 짧을수록 다른 스레드의 대기 시간이 줄어든다.


📌 핵심 요약

개념설명
Monitor Lock모든 Java 객체가 가진 내부 락
임계 영역한 번에 하나의 스레드만 실행 가능한 코드 구간
상호 배제Data Race 제거
메모리 가시성캐시 불일치 문제 해결
← 목록으로 돌아가기