가시성, volatile, 스테일데이터

Dayeon myeong·2022년 3월 4일
1

면접

목록 보기
11/35

가시성

동시성 문제에는 메모리 가시성 memory visibility문제도 발생할 수 있다. 가시성이란 값을 사용한 다음 동기화 블록을 빠져나가고 나면 다른 스레드가 변경 된 값을 즉시 사용할 수 있게 해야 한다는 뜻이다. 적절한 방법으로 동기화 시키지 않으면 다른 스레드에서 값을 제대로 사용하지 못하는 경우도 생길 수 있다. 최신 값이 아닌 스테일 데이터를 읽게 된다.

이러한 이유는 재배치 reordering 이라는 현상 때문이다. 재배치 현상은 특정 메소드의 소스코드가 100% 코딩된 순서로 동작하지 않고 재배치 된다는 것이다. 동기화 기능을 지정하지 않으면 컴파일러나 프로세서, JVM 등이 프로그램 코드가 실행되는 순서를 임의로 바꿔 실행하는 경우가 발생할 수도 있기 때문이다.

락과 가시성

synchronized와 같은 락은 상호배제뿐만 아니라 메모리 가시성을 확보하기 위해서도 사용한다. 변경 가능하면서 여러 스레드가 공유해 사용하는 변수를 각 스레드에서 각자 최신의 정상값으로 활용하려면 동일한 락을 사용해 모두 동기화시켜야한다.

volatile 키워드가 무엇을 해결하는데 사용하는 것인지 설명해주세요

멀티 스레드 환경에서 reorderring 재배치 현상을 막아서 가시성을 확보할 때 사용된다.

가시성이란 공유 데이터 값을 사용한 다음 동기화 블록을 빠져나가고 나면 다른 스레드가 변경 된 최신 값을 즉시 사용할 수 있게 해야 한다는 뜻이다. 오래된 값인 스테일 데이터를 읽지 않고 최신값을 읽을 수 있어야 한다.

이러한 가시성 문제가 발생하는 이유는 재배치 reordering이라는 현상 때문이다.소스코드가 100% 코딩된 순서로 동작하지 않을 수 있다는 것이다. 이는 JVM이나 컴파일러, 프로세서 등이 프로그램 코드가 실행되는 순서를 임의로 바꾸기 때문이다.

volatile을 쓰면 컴파일러와 런타임 모두 '이 변수는 공유해 사용하고, 따라서 실행 순서를 재배치 해서는 안된다'라고 이해한다. 그래서 CPU cache를 쓰지 않고 Main memory에서 최신의 값을 바로 읽는다.

synchronized로도 가시성과 상호배제가 확보되지만, synchronized는 어찌보면 비관적인 락과 비슷하게 스레드에 대해서 blocking해버리는 것이다. 가시성만을 확보해야하는 경우 volatile을 써도 무방하다.

예를 들어 다음과 같은 경우에 volatile을 쓸 수 있다.

  • 한 스레드에서만 쓰기 작업이 읽어나고, 다른 스레드들은 모두 읽기 작업만 하는 경우라면 이때는 volatile 을 사용해도 된다. synchronized를 쓰는 것은 매 작업시마다 blocking을 하기 때문에 volatile이 더 낫다.(반면 여러 스레드 쓰기 작업을 해야하는 경우에는 volatile보다는 synchronized를 써야 한다.)

  • double, long과 같은 64비트를 사용하는 숫자에 대해서도 가시성 효과를 볼 수 있다. volatile이 없는 double, long 형의 64비트 값에 대해서 메모리에 쓰거나 읽을 때 두 번의 32비트 연산을 사용하도록 허용한다. 따라서 volatile을 지정하지 않은 long 변수의 값을 쓰는 기능과 읽는 기능이 서로 다른 스레드에서 동작한다면, 이전 값과 최신 값에서 각각 32비트를 읽어올 가능성이 생긴다.

volatile은 어떻게 동작하냐면
값에 대해서 read와 write를 Main Memory에서 진행한다. 스레드마다 가지고 있는 CPU cache를 쓰지 않고 직접적으로 Main memory에 접근하기 때문에 비용이 더 크다.

원래 non-volatile 변수에 대한 작업은 성능 상의 이유로 스레드 별로 CPU cache를 사용한다. JVMdms 언제 CPU cache에 쓴 값을 메인 메모리에 올릴지, 메인 메모리 값을 CPU cache로 값을 읽을지 어떤 보장도 하지 않는다. 따라서 멀티 스레드 환경에서 스레드마다 가진 CPU cache에 저장된 값이 달라 변수 값 불일치 문제가 발생한다.

참고

자바 병렬 프로그래밍
https://junghyungil.tistory.com/99

profile
부족함을 당당히 마주하는 용기

0개의 댓글