강의 메모 - synchronized 기본 #
개요 #
- 자바는 단일 연산 특성을 보장하기 위해 synchronized 키워드를 제공하고 있으며 synchronized 구문을 통해 모니터 영역을 동기화 할수 있다
- synchronized 는 명시적으로 락을 구현하는 것이 아닌 자바에 내장된 락으로서 이를 암묵적인 락(Intrinsic Lock) 혹은 모니터락 (Monitor Lock) 이라고 한다
- 자바에 내장된 락 (암묵적인 락, 모니터락)
- synchronized 은 동일한 모니터를 가진 객체에 대해 오직 하나의 스레드만 임계영역에 접근할 수 있도록 보장하며 모니터의 조건 변수를 통해 스레드간 협력으로 동기화를 보장해 준다
- synchronized 가 적용된 한 개의 메서드만 호출해도 같은 모니터의 모든 synchronized 메서드까지 락에 잠기게 되어 락이 해제될 때 까지는 접근이 안되는 특징을 가지고 있다
- 앞에서 배운 ‘모니터’를 synchronized 키워드에 넣었으므로 모니터 장점을 가지고있음
- 락은 스레드가 synchronized 블록에 들어가기 전에 자동 확보되며 정상적이든 비정상적이든 예외가 발생해서든 해당 블록을 벗어날 때 자동으로 해제된다
- lock은 자동 확보/자동 해제
synchronized 는 모니터 락을 사용하여 동기화 할 수 있는 4가지 방법을 제공한다 #
- method
- synchronized method
- static synchronized method
- block
- synchronized block
- static synchronized method
- 원리는 동일
- 세부적으로는 인스턴스냐, 클래스냐 (method, block 각각 안에서도 세부적으로 나누는 기준)
- A 메서드 안에 4가지(위 구분 4가지)를 정의했다고 해보자. 몇개의 다른 모니터가 있을까?
- A 라는 클래스 안에 키워드(this)가 인스턴스를 참조하는 키워드다.
- 메서드 방식
- 첫번째는 this 라는 객체의 모니터를 가지고있는 것이다.
- 두번째는 static이 있으므로 A 자체의 모니터를 가지고 있는 것이다.
- 위 2개의 모니터가 다른 것이다.
- block 방식
- 세번째는 this
- 위 첫번째 모니터와 동일한 모니터가 되는 것이다.
- 네번째는 A 자체
- 위 두번째 모니터링과 동일한 모니터가 되는 것이다.
- 세번째는 this
- 첫번째-세번째, 두번째-네번째 모니터는 같다. 그러므로 다른 모니터는 2개가 있는 것이다.
- 모니터 안에 뮤텍스가 있음
- T1이 첫번재 메서드의 모니터 lock을 얻었을때 T2가 두번째 메서드의 모니터 락을 얻을 수 있다. (서로 다른 모니터이기 때문에)
- T1, T2가 동시에 첫번째 메서드 수행이 불가능한것 (T1이 이미 lock을 소지하고있기 때문에)
- T1이 첫번쨰 메서드 lock을 가지고있을때 T2가 세번째 메서드 접근 불가능 (첫번째, 메서드 세번째 메서드가 모니터 가 같기 때문)
- 결국 모니터가 같으면 같은 모니터를 가진 메서드 접근이 안되는거임
- 만약에 B 클래스에서 인스턴스를 생성했을때 세번째 메서드에 b를 넣었고, 네번째에 B.class 를 넣으면 위에 첫번째 두번째가 A 클래스 기준일떄 서로 다른 모니터를 가지고있께되어 각 스레드가 접근 가능하다.
- A 메서드 안에 4가지(위 구분 4가지)를 정의했다고 해보자. 몇개의 다른 모니터가 있을까?
모니터와의 관련성 #
- A 클래스가 있고, A 클래스의 인스턴스 생성, 모니터의 특징 중에서 모든 객체는 모니터를 가진다고 했는데 모든 객체를 세부적으로 나누면 A라는 클래스 타입의 객체, A를 통해서 생성한 인스턴스 객체 2개로 나눠질 수 있다. 2개로 나눴다는 것은 A클래스 타입의 객체와 A 인스턴스는 각각 다른 모니터를 가지는것이다. 이렇게 각각 다른 모니터를 가지는 이유는 자바에서 이렇게 설계했다. 이게 모니터의 기준 (A 클래스 기준으로 모니터를 2개 가질 수 있다는 것이다.)
synchronized 동기화 방식 #
메서드 동기화 방식 - synchronized method #
- 메소드 전체가 임계 영역(critical section)이 된다. 즉, 메소드 내의 모든 코드가 동기화 된다
- 동시성 문제를 한번에 편리하게 제어할 수 있는 장점은 있으나 메서드 내 코드의 세부적인 동기화 구조를 가지기 어렵다
- 메서드 전체를 동기화하기 때문에 동기화 영역이 클 경우 성능저하를 가져온다
- 인스턴스 메서드 동기화 와 정적 메서드 동기화 방식이 있다
블록 동기화 방식 - synchronized blcok #
- 특정 블록을 정해서 임계 영역(critical section)을 구성한다. 즉 블록 내의 코드만 동기화 된다
- 메서드 동기화 방식에 비해 좀 더 세부적으로 임계영역을 정해서 필요한 블록만 동기화 구조를 가질 수 있다
- 메서드 전체를 동기화 하는 것보다 동기화 영역이 작고 효율적인 구성이 가능하기 때문에 성능 저하가 덜하다
- 인스턴스 블록 동기화 와 정적 블록 동기화 방식이 있다
스레드 간 객체의 메서드를 동기화하기 위해서는 스레드는 같은 객체의 모니터를 참조하고 있어야 한다.