동시성 프로그래밍에서의 모니터(Monitor)

동기화의 도구

Posted by jay on August 23, 2021

1. 소개

이 글에서는 모니터가 무엇이며, Java에서 모니터를 사용하는 방법을 배웁니다.

2. 모니터란 무엇인가?

모니터는 스레드가 mutual exclusioncooperation를 가질 수 있도록 하는 동기화 메커니즘입니다.

  • mutual exclusion(상호 배제) – 하나의 스레드만이 특정한 시점에 메서드를 실행할 수 있습니다. locks기법을 사용합니다.
  • cooperation – 특정 조건이 충족될 때까지 스레드를 대기시키는 기능. wait-set을 사용합니다.

이 기능을 “모니터”라고 하는 이유 모니터는 스레드가 리소스에 어떻게 접근(access)하는 지 모니터링 하기 때문입니다.

(모니터는 70년대 초 PB Hansen이 Shared Classes 라는 이름으로 작성한 논문에서 공식적으로 관심을 받았습니다. 그 후 CAR Hoare는 Monitors – an Operating System Structuring Concept 라는 논문을 작성하여 Monitors 의 개념을 더욱 발전시켰습니다. 논문에서 그는 동기화의 한 형태를 소개하고 세마포어를 사용한 구현 모델을 제시했습니다.)

3. 모니터의 특징

모니터는 동시성 프로그래밍에 세 가지 주요 기능을 제공합니다:

  • 한 번에 하나의 스레드만 critical code section에 mutually exclusive(상호 배제적)으로 접근할 수 있습니다.
  • 모니터에서 실행 중인 스레드가 특정 조건이 충족될 때까지 차단될 수 있습니다.
  • 스레드는 조건이 충족될 때 다른 스레드에 알릴 수 있습니다.

4. Java에서 모니터 구현

critical section은 여러 스레드를 통해 동일한 데이터에 접근하는 코드이다.

Java에서는, critical sections를 표시하기위해 동기화된 키워드를 사용합니다. 이를 사용하여 메서드(synchronized methods - 동기화된 메서드라고도 함) 또는 코드의 더 작은 부분(synchronized statements)을 표시할 수 있습니다.

어떤 접근 방식을 선호하는지에는 두가지 의견이 있습니다. 일반적으로는 method synchronization가 더 간단한 접근 방식입니다. 하지만, synchronized statements은 보안 관점에서 더 좋을 수 있습니다.

Java에서는, 모니터와 모든 object 또는 클래스 사이에 논리적 연결이 있습니다. 따라서 모니터는 인스턴스 및 정적 메서드도 다룹니다. Mutual exclusion(상호 배제)은 모든 연관된 object 및 클래스에 대한 lock으로 수행됩니다. 이 잠금은 이진 세마포어(binary semaphore)이며, mutex라고 불립니다.

4.1. 건물의 전용실(exclusive room)으로 비유

monitor 메커니즘에 대한 Java의 구현은, 두 가지 개념을 가정한다 - entry setwait set. 저자는 건물과 전용실 비유를 사용하여 모니터 메커니즘을 표현합니다. 이 비유에서, 한 번에 한 사람만 전용실(exclusive room)에 있을 수 있습니다.

정리

  • 모니터는 두 개의 방과 하나의 복도가 있는 건물입니다.
  • 동기화된 리소스는 “전용실(exclusive room)”입니다.
  • wait set은 “대기실(wating room)”입니다.
  • entry set는 “복도(Hallway)”입니다.
  • 스레드는 전용실(exclusive room)에 들어가고 싶은 사람들입니다.

img

전용실(exclusive room)에 들어가고자 하는 사람(스레드)은 먼저 스케쥴러를 기다리는 복도(Hallay - entry set)로 갑니다 . 따라서 스케줄러는 그 사람(스레드)을 선택하여 전용실로 보냅니다.

JVM의 스케줄러는 우선순위 기반 스케줄링 알고리즘을 사용합니다. 두 개의 스레드가 동일한 우선 순위를 갖는 경우, JVM은 FIFO 방식을 사용합니다.

그래서 스케줄러가 사람(스레드)을 고르고, 그 사람은 전용실(exclusive room)로 들어간다. 이 방에서 어떤 특수한 상황이 발생하고 있을 수 있다면, 그 사람은 일단 나가서 전용실을 다시 사용할 수 있을 때까지 기다려야 합니다. 따라서 그 사람은 결국 다시 대기실(wait set)에 있게 됩니다. 따라서 스케줄러는 이 사람이 나중에 전용 방에 들어가도록 예약합니다.

중요한 단계들을 언급하자면

  • 건물에 들어가기 – 모니터에 들어가기
  • 전용실 입장 - 모니터 획득
  • 전용실에 있는 것 – 모니터를 소유하는 것
  • 전용방 나가기 - 모니터 해제
  • 건물에서 나가기 – 모니터에서 나가기.

다행히도, Java는 백그라운드에서 대부분의 작업을 이미 수행하기 때문에, 우리는 다중 스레드 응용 프로그램에서 세마포어를 직접 작성할 필요가 없습니다. 따라서 우리가 해야 할 일은 동기화된 키워드로 critical section을 래핑하는 것뿐입니다. 그러면 래핑된 section이 일시적으로 모니터 영역이 됩니다.

4.2 wait() and notify()

Java에서, wait()와 notify()는 동기화 된 블록에서 사용됩니다. 이 두 메서드는 스레드 간의 협업을 가능하게 하는 핵심 메소드입니다.

wait()는 호출하는 스레드의 모니터를 해제하고, 다른 스레드가 이 모니터에 들어가서 notify()를 호출할 때까지 sleep 모드로 전환하도록 명령합니다. 또한, notify()는 해당 객체에서 wait()를 호출한 첫 번째 스레드를 깨웁니다.

5. 결론

이 글에서는, 모니터의 개념과 Java에서의 구현에 대해 설명했습니다. 모니터는 동기화된 키워드 뒤에 숨겨진 핵심 동기화 메커니즘입니다 . 이것은 wait set와 entry set에 의존하며, 이것이 어떻게 작동하는지 간단한 비유를 통해 설명했습니다. 그리고 wait 및 notify 메소드의 사용법에 대해서도 알아봤습니다.

Baeldung의 동의하에 글을 번역하고 정리하였습니다.

참고 글: https://www.baeldung.com/cs/monitor