보다 더 사용하기 쉽고 기능도 추가된 락(lock)이 있습니다바로 모니터(monitor)인데요, 이번 영상에서는 모니터가 어떤 락이고, 어떻게 이루어져 있고, 어떤 식으로 동작하는지를 예제와 함께 자세히 설명합니다
참고로, 자바의 모든 객체는 모니터를 내부적으로 하나씩 가지고 있습니다
그래서 자바의 synchronized 키워드가 이 모니터와 밀접하게 관련이 있습니다
모니터는 mutual exclusion을 보장. 조건에 따라 스레드가 대기 상태(waiting)로 전환하는 기능이다.
critical section에 진입하려면 mutex lock을 취득해야한다.
mutex lock을 취득하지 못한 스레드는 큐(entry queue)에 들어간 후 대기(waiting)상태로 전환된다.
mutex lock을 쥔 스레드가 lock을 반환하면 -> signal() -> 락을 기다리며 큐에 대기 상태로 있던 스레드 중 하나가 critical section에서 실행된다.
waiting queue를 가진다.
조건이 충족되길 기다리는 스레드들이 대기 상태로 머무는곳
스레드가 자기 자신을 condition variable의 waiting queue에 넣고 대기 상태로 전환한다.
waiting queue에서 대기중인 스레드 중 하나를 깨운다.
waiting queue에서 대기중인 스레드 전부를 깨운다.
mutext lock을 취득하지 못한 스레드는 entry queue에서 대기 상태로 존재하다가, 작업을 마친 스레드가 lock을 반환하면서 signal 또는 broadcast하면 깨어나고 작업을 마친 스레드는 mutex lock을 반환한다.
스레드가 락을 취득했지만, 조건에 맞지 않는경우 wait를 호출하고 mutex lock과 condition variable이 파라미터로 전달되고, wait를 호출한 스레드는 자기자신을 waiting queue에 넣고 대기상태로 전환된다. 전환됨과 동시에 mutex lock을 반환해야한다.
만약 계속해서 락을 취득한 스레드가 조건이 안맞는 경우 condition variable이 관리하는 waiting queue에 계속 저장된다.
조건이 충족된 경우 signal 또는 broadcast를 호출하여 waiting queue에 존재하는 스레드를 깨운다.
entry queue : 뮤텍스에 의해 관리되는 queue
waiting queue : condition variable에 의해 관리되는 queue
buffer의 크기는 고정 되어 있다.
producer : 아이템을 생산하여 buffer에 저장한다.
consumer : buffer에 존재하는 아이템을 가지고 필요한 처리를 한다.
buffer의 크기가 가득찬 경우 producer가 buffer에 자리가 생길때 까지 확인 해야하나?
buffer의 아이템이 비어있는 경우 consumer는 계속해서 buffer에 아이템이 생성되는지 확인해야하나?
Buffer는 반드시 mutual exclusion이 보장되어 하나의 스레드만 작업해야한다.!!
1 ~ 3
c1은 lock을 획득하고 buffer가 비어있는지 확인한다. 비어있는 경우 lock을 반환하고 waiting queue에 들어간다.(현재는 buffer에 아이템이 존재한다 가정)
p1은 락을 얻기 위해 시도하지만, c1이 락을 획득했기 때문에 entry queue에서 lock을 획득할 수 있을때 까지 대기상태로 기다린다.
현재 다시 c1은 buffer를 확인하고 buffer가 비어있다. 때문에 wating queue에 들어가고 lock을 반환하여 조건이 충족될때까지 기다린다.
4 ~ 7
c1이 mutext lock을 반환했기 때문에 entry queue에 존재하던 p1에게 mutex lock을 전달한다.
lock을 획득한 p1은 buffer의 상태를 확인하고 buffer가 비어 있기 때문에 buffer에 아이템을 생성하고 signal 또는 broadcast를 통해 entiry queue에 존재하는 스레드를 깨운다.
5-1. p1이 lock을 반환하지 않고, 계속해서 buffer에 아이템을 쌓는 경우 (signal and continue)
5-2. p1은 대기상태로 들어가고, c1이 lock을 획득하고, 조건이 충족되서 buffer에 있는 아이템을 사용하는 경우 (signal and wait)
(signal and continue로 가정)
lock을 획득하지 못한 c1은 entry queue에 저장되고, p1은 아이템을 생성한다.
p1이 동작 중 p2, c2가 lock을 획득하기위해 왔지만, lock을 획득하지 못해서 entiry queue로 들어간다.
일반적인 queue라면 c1이 가장먼저 실행되어야 하지만, priority queue인 경우 우선순위에 따라서 실행 순서가 결정된다.
★ 스레드는 while문 안에서 자기 자신의 조건을 확인하는 구조이다.
대기 중이였다가 producer or consumer 상관없이 while문에 들어갈 때 lock을 반환하고, while문안에서 계속해서 자기 자신의 조건을 확인한다.
모니터를 직접 구현하는일은 거의 없고, 프로그래밍 언어가 모니터를 구현해놓고 지원한다.
★ 자바에서 모든 객체는 내부적으로 모니터를 가진다.
signal - notify
broadcast - notifyAll
synchronized에 의해 mutual exclusion이 보장된다.
synchronized(this)를 명시하면 자기 자신(해당 객체)의 mutex lock을 가지고 들어간다.
메서드에 설정하면 해당 객체의 lock을 가지고 메서드를 실행시킨다.
-->의미는 비슷하다.