메모리 모델

자바 메모리 모델을 숨겨주는 덮개를 열고 자바 메모리 모델이 보장하는 기능과 요구사항과 앞선 내용들의 실제 동작 원리에 대해 알아본다. JMM(Java Memory Model)은 변수에 저장된 값이 어느 시점부터 다른 스레드의 가시권에 들어가는지 JVM이 해야하는 최소한의 보장만 할 뿐임.

재배치

서로 다른 스레드가 각자의 상황에 맞는 순서로 명령어를 실행할 수 있음. 특정 작업이 지연되거나 다른 순서로 실행되는 것처럼 보이는 문제

각 스레드 내부에서 일어나는 작업은 다른 스레드와 연결 관계가 없어서 재배치되어 실행될 가능성이 있다.

자바 메모리 모델을 간략하게 설명한다면

미리 발생(happens-before)

재배치가 가능하지만 필수적으로 지켜야 할 순서는 있다. 작업 A가 실행된 결과를 작업 B에서 볼 수 있다는 점을 보장하기 위해 작업 A와 B 사이에는 미리 발생 관계가 갖춰져야 한다.

미리 발생 규칙

프로그램 순서 규칙 : 동일 스레드 내에서 앞 코드가 뒤 코드 보다 먼저 실행된다.
모니터 잠금 규칙
volatile 변수 규칙 : volatile 변수에 대한 쓰기 작업은 이후의 해당 변수 읽기 작업보다 미리 발생함
스레드 시작 규칙 : 특정 스레드의 start 작업은 스레드 내부 로직보다 미리 발생함.
스레드 완료 규칙 : 스레드 내부 작업은 다른 스레드에서 해당 스레드가 완료됐다는 점을 파악하기 전에 미리 발생한다.
인터럽트 규칙 : 다른 스레드를 대상으로 interrupt 호출하는 작업은 인터럽트 당한 스레드에서 인터럽트 당한 사실 파악하는 일보다 미리 발생함.
완료 메소드 규칙 : 특정 객체 생성 메소드 완료 시점은 완료 메소드 시작 시점보다 미리 발생함.
전이성 : A가 B보다 미리 발생하고 B가 C보다 미리 발생한다면, A는 C보다 미리 발생함.

작업이 부분적으로 순서가 정해져 있다 해도 동기화 작업은 항상 완전하게 순서가 정해져 있다. 두 개의 스레드가 서로 다른 락으로 동기화 되있다면, 서로 간의 순서에 대해 보장할 수 없다.

더블 체크 락

동기화 기법이 주는 영향을 최소화하고자 하는 기발한 방법들이 있다.

하지만, 더블 체크락은 문제가 있기 때문에 사용하지 말아야 한다.

Last updated