참고자료
두번째 영상은 정말 좋아요 구독을 누를수밖에 없는 엄청난 퀄리티이다.
비슷한 내용은 대부분 영상의 정보를 활용했다. 시간이 없다면 영상만 봐도 좋을듯 하다.
사전에 알아두면 좋을만한 링크
모니터?
모니터는 언제 필요한가?
- 한번에 하나의 쓰레드만 실행 되어야 할때
- 여러 쓰레드와 협업이 필요 할때
즉 동시성에 대한 얘기.
모니터의 구성요소
- mutext : 크리티컬섹션에서 mutual exclusion 을 보장하는 장치.
- mutext lock을 취득하지 못한 쓰레드는 큐에 들어서 waiting 상태로 대기.
- mutext lock을 쥔 스레가 lock 을 반환하면, 락 기다리던 대기 쓰레드중 하나가 실행된다
- cv (condition variable)
- wq (wating queue) 를 갖고있음. 조건이 충족되길 기다리는 쓰레드들이 대기상태로 머무르는 큐
자바는 synchronized 키워드와 함께 모니터와 락을 사용한다.
cv (condition variable) 의 주요동작
- wait - 자기 자신을 cv 의 wq 에 넣고 대기상태로 전환함
- signal - wq 에서 대기중인 쓰레드중 하나를 깨움
- broadcast - 전부 깨움
모니터와 크리티컬섹션
전반적으로 모니터와 함께 크리티컬섹션을 처리하는 모습.

출처 : https://www.youtube.com/watch?v=Dms1oBmRAlo
사용되는 2개의 큐
- entry q : 크리티컬섹션 진입을 기다리는 큐
- waiting q : 조건이 충족되길 기다리는 큐
JAVA 모니터 특징
- 모든 객체는 모니터를 갖고있다.
- 모니터의 3가지 동작 (모두 자신이 속한 객체가 속한 모니터의 cv에 대한 동작들임)
- wait - wait
- notify - signal
- notifyAll - broadcast
- 모니터에는 mutex lock 이 있다.
- mutual exclusion 은 synchronized 키워드로 해결한다.
- cv (condition variable) 는 하나만 내부에 가지고 있다.
notify는 객체의 모니터에 대기중인 쓰레드들중 랜덤으로 1개를 깨운다. (어떤게 될지는 비결정적)
notifyAll은 객체의 모니터에 대기중인 쓰레드들을 모두 깨운다.
대체로 notifyAll이 더 실용적일 거라고 함. (여기저기 대부분 예제가 notifyAll 이긴 하더라)
But in most cases, it would be more viable to implement notifyAll().
출처-밸덩
생산소비 문제 해결

출처 : https://www.youtube.com/watch?v=Dms1oBmRAlo
특이사항 :
- while 쓰는 이유는, OS에 따라 다르지만 wait 였던걸 잘못 깨워버리는 경우도 있다고 한다. 따라서 깨어난 후, 다시 한번 조건을 체크하기 위해 if가 아니라 while을 쓴것.
- 자바 객체의 모니터는 condition variable 이 1개만 있다고 간주한다. 따라서 선별적으로 signal 해줄수가 없다. 특정 쓰레드를 깨우는 notify 보다는, 모니터 내 대기큐에 있는 모든 쓰레드를 깨우는 notifyAll 를 썼다. 해서, 방금 notifyAll() 하며 일을 마치고 나온 쓰레드도 다시 entry q에 들어갔다가 또다시 자원을 할당받고 수행할수도 있는 비효율성이 있어보인다.
자바에서 조건에 맞는 쓰레드만 깨우려면 java.util.concurrent 의 ReantratLock + Condition 를 활용하면 된다.
결론
동시성을 활용하기 위해 모니터라는 개념을 알았다.
모니터는 java에만 있는 개념은 아니며 몇가지 기능 (wait, signal, broadcast) 을 이용해 여러 쓰레드간에 협력을 만들어낼수 있다.
java는 wait, notify, notifyAll로 대응된다. notify 대신 notifyAll 이 편리 할 것이다.
java는 객체가 모니터를 가지고 있으며, 모니터 내에 condition variable은 1개만 관리하고 있다.
쓰레드는 os에 따라 비결정적 이라는 특징 때문에 while을 쓰는 모습 등 저수준 코드로는 구현이 어렵다.
가독성, 편의성, 기능 모든면에서 1.5의 동시성라이브러리 java.util.concurrent 를 이용하는게 좋다.
그럼에도 저수준 코드도 이해 해 두는것은 동시성라이브러리를 깊게 이해 하는데 도움이 된다.