아무거나 개발공부/JAVA 기초다지기

java에서 모니터 사용하기 - synchronized

코드 살인마 2022. 11. 7. 20:29
728x90

세마포어는 실제로 매우 오래된 동기화 도구이다. 현재에는 모니터(monitor)라는 동기화 도구를 주로 사용하며, 이는 좀 더 고수준의 동기화 기능을 제공한다.

 

QuickSort 알고리즘으로 유명한 C. A. R. Hoare(호어)의 논문에서 처음 등장한 개념이다. 하나의 객체마다 하나의 모니터를 결합할 수 있으며, 모니터와 결합된 객체는 잠금(lock) 기능을 가지고 있어 하나의 쓰레드만 접근 가능한다.

모니터 구조

![[Pasted image 20221107200903.png]]

위는 모니터 구조를 나타낸 그림이다. 모니터는 공유 자원 + 공유 자원 접근함수로 이루어져 있고, 2개의 큐를 가지고 있다. 각각 mutual exclusion(상호배타) queue, conditional synchronization(조건동기) queue이다.

  • 상호배타 큐는 말그대로 공유 자원에 하나의 프로세스만 진입하도록 하기 위한 큐이다.
  • 조건동기 큐는 이미 공유자원을 사용하고 있는 프로세스가 특정한 호출 wait()을 통해 조건동기 큐로 들어갈 수 있다.

조건동기 큐에 들어가 있는 프로세스는 공유자원을 사용하고 있는 다른 프로세스에 의해 깨워줄 수 있다. 이 역시 깨워주는 프로세스에서 특정한 호출 notify()을 해주며, 깨워주더라도 이미 공유자원을 사용하고 있는 프로세스가 해당 구역을 나가야 비로소 큐에 있던 프로세스가 실행된다.

 

자바는 모니터를 제공하는 대표적인 언어이며, 자바의 모든 개체는 모니터가 될 수 있다. 그렇다면 자바를 통해 모니터에 대한 예제를 살펴보자.

class C {
  private int value, ...;     // 공유 변수
  synchronized void Foo() {   // 배타동기
    // ...
  }
  synchronized void Goo() {
    // ...
  }
  void H() {
    // ...
  }
}

위 코드는 모니터를 사용하고 있는 클래스이다. value와 같은 변수들은 여러 쓰레드가 공유하고 있는 변수로 볼 수 있고, synchronized키워드는 배타동기를 수행하는 함수를 말한다. 즉, 해당 함수에는 단 하나의 쓰레드만 접근할 수 있다.

 

Foo()함수와 Goo()함수는 synchronized 키워드를 통해 상호배타 함수로 선언하였는데, 이는 둘 다 같은 임계구역을 갖는다는 의미이다. 다시 말해서, Foo()함수에 한 쓰레드가 수행 중이라면, Foo()함수뿐 아니라 Goo()함수에도 다른 쓰레드는 접근할 수 없다.

 

반면에 H()함수는 일반 함수인데, 이 함수에서는 공통 변수에 대한 업데이트를 하지 않는다는 것을 예상할 수 있다. (여러 쓰레드가 동시에 접근가능하기 때문에 문제발생)

모니터로 런타임 이후 데이터 싱글턴에 초기화하기

싱글톤 패턴인 TestConfig Class에 값을 할당하는 DCL(Double Checked Lock) 방식이다.
synchronized를 메서드에 결합하는 방법 이외에 아래와 같이 사용할 수도 있다.

private static TestConfig instance = null;

public static TestConfig getInstance() {
    if (instance == null) {  
       synchronized (TestConfig.class) {        // synchronized를 이런식으로도 사용가능하다.
          if(instance == null) {
              instance = new TestConfig();  
              instance = getData("TestConfig"); // 인스턴스에 값 할당 
          }
       }  
    }  
    return instance;
}

위 방법은 현재 Broken 한 코드로 사용을 권하지 않고 있다. 이에 관한 내용은 다음 링크를 참고하자.

REFERENCE

codemcd - https://velog.io/@codemcd/운영체제OS-11.-모니터