목차

78. 공유 중인 가변 데이터는 동기화해 사용하라.


Previous

synchronized

Volatile

개요

synchronized 키워드를 통해 메서드 혹은 블록을 잠금(Lock)으로써 한 번에 한 스레드만 수행할 수 있도록 할 수 있다. 그리고 대부분 이 기능을 한 스레드가 점유 혹은 변경중에 상태가 일관되지 않은 순간을 다른 스레드에서 보지 못하도록 하는 용도로만 생각한다.

그런데, 여기에 동기화의 중요한 기능을 하나 더 얘기할 수 있다. 바로 동기화된 메서드나 블록에 들어간 스레드가 같은 락의 보호하에 수행된 모든 이전 수정의 최종 결과를 보게 해준다.

원자성(atomic)

언어 명세를 보면 long, double을 제외하고는 변수를 읽고 쓰는 동작이 원자적이라 한다.

멀티 스레드 환경에서 변수를 따로 동기화 하지 않고 수정하더라도 스레드가 정상적으로 저장한 값을 온전히 읽어옴을 보장한다는 의미이다.

그래서 얼핏 동기화를 하지 않아도 될 것 같지만, 이는 위험한 생각이다.

자바 언어 명세는 스레드에서 필드를 읽을 때 수정이 반영된 값을 얻는다고 보장하지만, 한 스레드가 저장한 값이 다른 스레드에게 보이는지는 보장하지 않는다.

그렇기에 동기화는 배타적 실행 뿐 아니라 스레드 사이의 안정적인 통신에도 필수다.

자바의 메모리 모델

자바의 메모리 모델은 한 스레드가 만든 변화를 다른 스레드에게 언제 어떻게 보일지를 규정하고 있기 때문인데, 이 때문에 공유 중인 가변 데이터를 동기화에 실패하면 문제가 발생할 수 있다.