개발 공부/Java & Spring

20. volatile

빵다희 2023. 3. 9. 12:34
volatile 
: 변수의 앞에 붙이면 cpu의 코어가 변수의 값을 읽어올 때 캐시가 아닌 메모리에서 읽어서 캐시와 메모리간의 값의 불일치가 해결된다.

* volatile이 필요한 이유

멀티 코어 프로세서에서는 코어마다 별도의 캐시를 가지고 있는데
코어는 메모리에서 읽어온 값을 캐시에 저장하고 캐시에서 값을 읽어서 작업한다.
다시 같은 값을 읽어올 때에는 먼저 캐시에 있는지 확인하고 없을때만 메모리에서 읽어온다.
그러다가 도중에 메모리에 저장된 변수의 값이 변경되어도 캐시에 저장된 값이 갱신되지 않아서 메모리에 저장된 값이 다른 경우가 발생한다. 

* volatile의 사용방법

//boolean stopped = false;

//volatile 
volatile boolean stopped = false; 

//synchronized블럭을 사용해도 캐시와 메모리간의 값 동기화가 이루어진다.
public sysnchronized void stop(){
   stopped = true;
}

 

long과 double의 원자화
 : JVM은 데이터로 4byte(=32bit)단위로 처리하기 때문에 int 이하의 작은 타입들은 한번에 처리가 가능하나,
   크기가 8byte인 long과 double타입의 변수는 한번에 처리하지 못해 중간에 다른 쓰레드가 끼어들 수도 있다.
   끼어들지 못하게 할 때 volatile을 변수 앞에 붙여 해당 변수를 원자화시킨다.

* 활용방법

//상수에는 volatile을 붙일 수 없다. 상수는 변하지 않는 값이므로 멀티쓰레드에 안전하다. 그래서 붙일 필요가 없다.
volatile long sharedVal;    // long타입의 변수(8byte)를 원자화
volatile double sharedVal;  // double타입의 변수(8byte)를 원자화

* 주의할 점 

volatile은 변수의 읽기나 쓰기를 원자화 할 뿐, 동기화 시키지는 않는다. 

그래서 동기화가 필요할 때 synchronized블럭 대신 volatile을 쓸 수 없다. 

728x90
반응형

'개발 공부 > Java & Spring' 카테고리의 다른 글

22. 스트림의 최종연산  (0) 2023.03.26
21. fork & join 프레임워크  (0) 2023.03.09
19. 쓰레드의 동기화  (0) 2023.03.09
18. 애너테이션(annotation)  (0) 2023.02.15
17. 열거형(enums)  (0) 2023.02.12