[자바] 쓰레드의 동기화

June·2021년 8월 15일
1

자바

목록 보기
36/36

멀티쓰레드 프로세스의 경우 여러 쓰레드가 같은 프로세스 내의 자원을 공유해서 작업하기 때문에 서로의 작업에 영향을 주게 된다. 이러한 일을 방지하기 위해 임계 영역(Critical Section잠금(락, lock)이 있다.

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

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

자바에서는 synchrozied 블럭을 이용해서 쓰레드의 동기화를 지원했지만, JDK1.5부터는 다양한 패키지를 통해 지원한다.

9.1 synchroized를 이용한 동기화

이; 키워드는 임계 영역을 설정하는데 사용된다.
1. 메서드 전체를 임계 영역으로 지정

public synchroized void calcSum() {
  //
}

메서드 전체가 임계영역으로 설정된다. 쓰레드는 synchroized 메서드가 호출된 시점부터 해당 메서드가 포함된 객체의 lock을 얻어 작업을 수행하다가 메서드가 종료되면 lock을 반환한다.

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

synchronized (객체의 참조변수) {
  // ...
}

두 번째 방법은 코드 일부를 블럭{}으로 감싸고 블럭앞에 'synchroized (참조변수)'를 붙이는 것인데, 이때 참조변수는 락을 걸고자하는 객체를 참고하는 것이어야 한다. 이 블럭을 synchroized 블럭이라고 부른다.

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

임계 영역은 멀티쓰레드 프로그램의 성능을 좌우하기 때문에 가능하면 메서드 전체에 락을 거는 것보다 synchroized 블럭으로 임계 영역을 최소화해서 보다 효율적인 프로그램이 되도록 노력해야 한다.

출처: 자바의 정석

Java Language Specification

The Java programming language neither prevents nor requires detection of deadlock conditions. Programs where threads hold (directly or indirectly) locks on multiple objects should use conventional techniques for deadlock avoidance, creating higher-level locking primitives that do not deadlock, if necessary.

데드락에 대해서는 프로그래머가 알아서 전통적인 방법으로 해결을 해야하는 듯하다.
https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html

0개의 댓글