JAVA/포스팅

자바 쓰레드의 동기화

짜집퍼박사(짜박) 2023. 11. 21. 23:51

자바에서 쓰레드 동기화는 여러 쓰레드가 공유 자원에 접근할 때 발생하는 문제를 해결하기 위한 기술입니다. 주로 데이터의 일관성과 정확성을 보장하기 위해 사용됩니다. 아래는 쓰레드 동기화에 관련된 주요 개념과 메커니즘입니다.

 

1. 임계 영역 (Critical Section)

- 여러 쓰레드가 공유 자원에 동시에 접근하는 부분을 "임계 영역" 또는 "Critical Section"이라고 합니다.
- 여러 쓰레드가 동시에 접근하면 문제가 발생할 수 있기 때문에 이 부분을 동기화해야 합니다.

 

2. 동기화 메서드와 동기화 블록

메서드 전체를 동기화하려면 메서드에 synchronized 키워드를 사용할 수 있습니다.

public synchronized void synchronizedMethod() {
    // 동기화가 보장된 메서드 영역
}

특정 블록을 동기화하려면 synchronized 블록을 사용할 수 있습니다.

public void someMethod() {
    // 비동기 영역

    synchronized (lockObject) {
        // 동기화가 보장된 블록 영역
    }

    // 비동기 영역
}

 

3. 락 (Lock) 및 락 객체

- 자바에서는 모든 객체는 락(lock)을 가지고 있습니다.
- synchronized 키워드는 객체의 락을 사용하여 동기화를 구현합니다.

private final Object lockObject = new Object();

public void synchronizedMethod() {
    synchronized (lockObject) {
        // 동기화가 보장된 블록 영역
    }
}

 

4. 임계 영역 진입 대기와 획득

- 락을 획득하려는 쓰레드가 없으면 대기 상태로 들어가고, 다른 쓰레드가 락을 반납하면 대기 중인 쓰레드 중 하나가 락을 획득합니다.
- 락이 획득된 상태에서만 해당 동기화 영역에 진입할 수 있습니다.

 

5. 임계 영역에서의 락 해제 (Lock Release)

synchronized 블록이나 메서드의 종료 또는 예외 발생 시 락이 자동으로 해제됩니다.

 

6. 쓰레드 대기와 통지

- wait(), notify(), notifyAll() 메서드를 사용하여 쓰레드 간에 대기하고 통지할 수 있습니다.
- wait() 메서드는 쓰레드를 대기 상태로 만들고, notify() 또는 notifyAll() 메서드로 다시 깨울 수 있습니다.

synchronized (lockObject) {
    while (condition) {
        lockObject.wait(); // 대기
    }

    // 조건이 충족되면 실행

    lockObject.notify(); // 대기 중인 쓰레드 중 하나 깨우기
    // 또는
    lockObject.notifyAll(); // 대기 중인 모든 쓰레드 깨우기
}

 

7. Volatile 변수

- volatile 키워드를 사용하여 변수를 선언하면 해당 변수에 대한 쓰레드 간의 가시성이 보장됩니다.
- 쓰레드는 항상 메모리에서 최신 값을 읽고 쓸 수 있습니다.

private volatile boolean flag = false;

쓰레드 동기화는 쓰레드 간의 경쟁 조건(race condition)이나 데드락(deadlock)과 같은 문제를 방지하고, 데이터의 일관성을 유지하기 위해 중요합니다. 그러나 과도한 동기화는 성능에 부정적인 영향을 미칠 수 있으므로 신중하게 사용해야 합니다.

 

With ChatGPT