Language/Java

12.3 쓰레드(Thread) - Synchronized를 이용한 동기화

리져니 2021. 7. 29. 01:51

멀티쓰레드 프로세스의 경우 여러 쓰레드가 같은 프로세스 내의 자원을 공유해서 작업하기 때문에, 서로의 작업에 영향을 주게된다.

이러한 점에서 멀티쓰레드로 작업을 했을때 원래 의도했던 것과는 다른 결과를 얻을 수가 있는데, 이러한 일의 발생을 방지하기 위해서 한 쓰레드가 특정 작업을 끝마치기 전까지 다른 쓰레드에 의해 방해받지 않도록 하는 것이 필요하다.

 

이것이 바로 '임계 영역(critical section)'과 '잠금(lock)'이다.

공유 데이터를 사용하는 코드 영역을 임계 영역으로 지정해놓고, 공유 데이터(객체)가 가지고 있는 lock을 획득한 단 하나의 쓰레드만 이 영역 내의 코드를 수행할 수 있게 한다.

그리고 해당 쓰레드가 임계 영역 내의  모든 코드를 수행하고 벗어나서 lock을 반납해야만 다른 쓰레드가 반납된 lock을 획득하여 임계 영역의 코드를 수행할 수 있게된다.

 

한 쓰레드가 진행 중인 작업을 다른 쓰레드가 간섭하지 못하도록 막는 것을 쓰레드의 동기화(synchronization)라고 한다.

 

Synchronized를 이용한 동기화

synchronized 키워드(임계 영역을 설정하는데 사용)

1. 메서드 전체를 임계 영역으로 지정하기

public synchronized void calcSum() {
	// 임계 영역
}

메서드 앞에 synchronized 키워드를 붙임으로써 메서드 전체가 임계 영역으로 설정된다.

쓰레드는 synchronized메서드가 호출된 시점부터 해당 메서드가 포함된 객체의 lock을 얻어 작업을 수행하다가 메서드가 종료되면 lock을 반환한다.

 

2. 특정한 영역을 임계 영역으로 지정하기

synchronized(객체의 참조변수){
	// 임계 영역
}

메서드 내의 코드 일부를 블럭으로 감싸고 블럭 앞에 synchronized를 붙임으로써 해당 블럭(synchronized 블럭)을 임계 영역으로 설정한다. 이때 참조변수는 lock을 걸고자하는 객체를 참조하는 것이다.

이 블럭의 영역 안으로 들어가면서 부터 쓰레드는 지정된 객체의 lock을 얻게되고, 블럭을 벗어나면 lock을 반환한다.

 

모든 객체는 lock을 하나씩 가지고 있으며, 해당 객체의 lock을 가지고 있는 쓰레드만 임계 영역의 코드를 수행할 수 있다. (다른 쓰레드들은 lock을 얻을 때까지 기다리게됨)

 

* 1번보다는 2번으로 임계 영역을 최소화해서 효율적인 프로그램을 만드는게 좋다.

 

 

wait()와 notify()

특정 쓰레드가 객체의 lock을 가진 상태로 오랜 시간을 보내지 않도록 하는 것도 중요하다.

이러한 상황을 개선하기 위해 고안된 것으로,

동기화된 임계영역의 코드를 수행하다가 작업을 더이상 진행할 상황이 아니라면 일단 wait()을 호출하여 쓰레드가 lock을 반납하고 기다리게 한다. 그러면 다른 쓰레드가 lock을 얻어 해당 객체에 대한 작업을 수행할 수 있게 된다.

나중에 작업을 진행할 수 있는 상황이 되면 notify()를 호출해서 작업을 중단했던 쓰레드가 다시 lock을 얻어 작업을 진행할 수 있게 한다.

(wait()이 호출되면, 실행 중이던 쓰레드는 해당 객체의 대기실(waitting pool)에서 기다린다. notify()가 호출되면 해당 객체의 대기실에 있던 모든 쓰레드 중에서 임의의 쓰레드만 다시 작업을 진행한다)

* wait()과 notify()는 특정 객체에 대한 것이므로, Object클래스에 정의되어있다.

wait()은 notify()나 notifyAll()이 호출될 때까지 기다리지만, 매개변수가 있는 wait은 지정된 시간만 기다린다. (지정된 시간이 지난 후에 자동적으로 notify가 호출됨)

waitting pool은 객체마다 존재하는 것이므로 notifyAll()이 호출된다고 모든 객체의 waitting pool에 있는 쓰레드가 깨워지는 것은 아니고, notifyAll()이 호출된 객체의 waitting pool에 대기중인 쓰레드만 해당된다.

 

 

 

728x90