멀티스레드 환경에서의 프로그래밍 시 동시성 문제를 제어해야할 필요성이 있다. 하나의 자원에 여러 스레드가 접근 시 개발자가 예상하지 못 한 결과를 초래할 수 있다. 이러한 멀티스레드 환경에서 동시성 제어를 위해 사용되는 Synchronized 키워드에 대해 학습하고자 한다.
Synchronized 우리 말로 '동기화된'이라는 뜻이다. 자바에서의 Synchronized는 말 그대로 공유될 가능성이 존재하는 자원에 대해 동기화를 제어할 수 있게 해주는 키워드이다. 자바에서 해당 키워드를 붙일 경우 해당 자원에 대해 오직 하나의 스레드만 접근할 수 있다. 어떠한 스레드가 해당 자원에 접근 중이고 다른 스레드가 같은 자원에 접근하려고 할 경우 접근을 대기시킨다.
Synchronized 키워드는 동기화가 필요한 메서드나 코드 블럭 앞에 사용할 수 있다.
public synchrozied void incrementCount() {
this.count++;
}
다음과 같이 메서드에 synchronized 키워드를 사용할 경우 해당 메서드는 동시에 오직 하나의 스레드만 실행할 수 있다.
public void incrementCount() {
synchronized(this) {
count++;
}
}
다음과 같이 this(인스턴스 자신을 참조하는) 객체나 특정 객체에 대한 블록에 synchronized 키워드를 붙이면, 해당 객체에 대한 모든 스레드의 접근이 동기화된다.
synchronized 키워드를 사용하여 동기화된 메서드나 코드 블록에 진입하려는 스레드는 먼저 모니터링 락(lock)을 획득해야 한다. 만약 모니터링 락이 다른 스레드에 의해 이미 획득되어 있는 경우 해당 스레드는 대기 상태에 들어가고, 진행 중인 스레드가 모니터링 락을 반납할 때까지 대기한다. 이 과정에서 운영체제는 대기 중인 스레드를 차단시키지 않고 대기 상태를 유지하면서 CPU를 절약한다.
synchronized 키워드를 사용할 때 주의할 점은 다음과 같다.