Volatile

개발하는개발자·2022년 10월 4일
0

Java Thread

목록 보기
9/10

Volatile

왜 사용하는가?

Volatile은 스레드들에 대한 변수 변경의 가시성을 보장해준다.

성능상의 이유로 non-volatile 변수의 값은 CPU 캐시를 이용해 읽어온다. volatile 키워드를 사용하면 해당 변수에 대한 모든 작업들은 메인 메모리에서 이루어지게 된다.

결국은 동기화의 문제

해당 구조에서 Volatile로 선언된 변수가 아니라면 counter 변수가 CPU Cache에서 Main MeMory로 기록이 될지 알 수 없기 때문에 두 CPU가 다른 counter 값을 가질 수 있다.
이렇게 특정 스레드가 변경한 값이 Main MeMory에 저장되지 않아 다른 스레드가 값을 볼 수 없는 상황을 '가시성'문제라고 한다.

Happens-Before

Volatile 변수가 메인 메모리에 저장이 될때 해당 변수만이 아닌 스레드가 작업한 그 이전의 모든 변수들도 메인 메모리에 함께 저장된다. 그렇게 때문에 개발자는 특정 변수에만 Volatile을 선언함으로써 가시성을 해결할 수 있다.

Volatile로도 해결할 수 없는 동기화 예시

한 스레드가 특정 변수에 대한 쓰기 작업만을 하고 다른 스레드에서는 읽기 작업만 한다면 문제가 발생하지 않는다.
하지만 두 스레드가 하나의 변수에 대해 쓰기 작업을 하는 경우는 Volatile로 해결할 수 없다. 그림의 예시로 Main Memory에 counter값은 0이고 두 스레드가 증가를 시키는 작업을 한다면 애플리케이션 오류로 이어진다.

Volatile을 이용해 변수 원자화

JVM은 4byte단위로 처리하기 때문에 long, double의 경우 하나의 명령어로 값을 읽거나 쓸 수 없다.
동기화를 고려해야 하는 경우 Volatile을 사용해주면 해당 작업을 하나의 명령어로 처리할 수 있다. 하지만 기본적으로 Main Memory를 이용하는 작업이기 때문에 가시성 보장이 반드시 필요한 경우에만 사용하는것이 좋다

profile
하루에 하나씩 배우자

0개의 댓글