[CS/운영체제] 멀티스레드와 동시성 - 13부

황제연·2025년 7월 6일
0

CS학습

목록 보기
127/193
post-thumbnail

Object- wait, notify

자바의 Object 클래스는 생산자 소비자 문제를 해결할 수 있는
wait(), notify() 메소드를 제공합니다

wait()

Object.wait()은 현재 스레드가 가진 락을 반납하고 WAITING합니다
현재 스레드를 WAITING 상태로 전환하며, 메소드는 현재 스레드가 synchronizer 블록이나
메소드에서 락을 소유하고 있을 때만 호출할 수 있습니다

호출한 스레드는 락을 반납하고 다른 스레드가 락을 획득할 수 있도록 합니다
대기상태로 전환된 스레드는 다른 스레드가 notify() 또는 notifyAll()을 호출할 때까지
대기상태를 유지합니다

notify()

대기중인 스레드 중 하나를 깨웁니다
이 메소드 또한 synchronizer 블록이나 메소드에서 호출되어야하며,
깨운 스레드는 락을 다시 획득할 기회를 얻습니다

만약 대기 중인 스레드가 여러개라면 그중 하나만 깨워집니다

notifyAll()

대기중인 모든 스레드를 깨웁니다
이 메소드 역시, 블록이나 메소드에서 호출되어야 하며, 모든 대기중인 스레드가
락을 획득할 수 있는 기회를 얻습니다

이 방법은 모든 스레드를 깨워야할 필요가 있는 경우 유용합니다

앞선 예제에 적용한다면

앞선 예제에서는 스레드가 락을 획득한 TIMED_WAITING 상태가 되어있었기 때문에
다른 스레드가 접근할 때 BLOCKING 되는 문제가 발생했습니다

이번에는 각 상황에서 접근할 때, 버퍼 큐가 가득차있으면 wait()을 통해
현재 스레드가 락을 반납하도록 할 수 있습니다
이렇게 하면 현재 스레드는 RUNNABLE에서 WAITING 상태가 됩니다

이후, 큐에 넣는 과정에서 notify()를 통해 대기하는 스레드에 해당 정보를 알려줘서 깨워주고
저장된 데이터를 획득할 수 있습니다

스레드 대기 집합

Object.wait()을 호출해서 스레드가 WAITING 상태가 되었을 때, 관리하는 것을 대기집합(wait set)
이라고 합니다
모든 객체는 각자의 대기 집합을 가지고 있습니다
즉, 모든 객체는 모니터락과 대기집합을 가지고 있습니다

따라서 락을 획득한 객체의 대기집합을 사용해야합니다
이후, notify()를 통해 스레드 대기집합에 신호를 주면 깨어날 수 있는데
이렇게 깨어난 스레드가 바로 동작하는 것은 아닙니다
깨어난 스레드는 여전히 임계영역에 있기 때문에 락을 획득하기 위해 BLOCKED 상태로
대기합니다

임계영역 안에서 2개의 스레드가 실행되면 문제가 발생하므로 당연히 락을 가지고 있는
하나의 스레드만 실행되어야 합니다
그렇기 때문에 락을 획득하기 전까지 BLOCKED 상태로 대기합니다

notify()로 어떤 스레드를 깨울까?

그렇다면 notify()로 대기집합에 있는 어떤 스레드를 깨울까요?
정답은 알 수 없다입니다
JVM 스펙에 명시되어 있지 않으며 버전 환경 등에 따라 달라집니다

한계

앞선 notify()로 어떤 스레드를 깨울지 모르는 문제때문에, 생산자 스레드가 생산자를 깨우거나
소비자 스레드가 소비자를 깨우는 동일한 역할을 하는 스레드가
깨울 때 비효율이 발생합니다

여전히 가득차있거나, 여전히 비어있기 때문에 각 스레드가 다시 자신의 스레드 대기집합으로
들어가며, 비효율적인 반복이 이루어집니다

스레드 기아 (thread starvation)

또 다른 문제로 스레드 기아 문제도 존재합니다
notify()로 어떤 스레드를 깨울지 알 수 없기 때문에, 최악의 경우, 특정 스레드만
반복해서 깨어날 수 있습니다

아예 어떤 스레드는 엄청 나중에 깨어날 수도 있습니다
이렇게 대기상태의 스레드가 실행 순서를 계속 얻지 못해서 실행되지 않는 상황을
스레드 기아상태라고 합니다

스레드 기아 해결 방법

이런 스레드 기아 문제를 해결하는 방법은 notifyAll()을 사용해서 스레드 대기 집합에 있는
모든 스레드를 한번에 다 깨우는 것입니다
하지만 모든 스레드가 다 BLOCKED 상태가 되며, 다시 스레드 대기 집합으로 들어가게 되고
여전히 비효율의 문제는 해결되지 않습니다

참고

  • 김영한의 실전 자바 - 고급 1편
profile
Software Developer

0개의 댓글