실제로 가지고 있는 데이터가 RAM에서 실시간으로 변경이 되었다고 했을 때, 언제 시시각각으로 CPU Cache Memory가 아닌 RAM에서 데이터를 곧바로 읽어 들여서 CPU Cache Memory를 업데이트 할련지 시간차도 보장할 수 없다...
곧, 동시성 프로그래밍에서는 CPU와 RAM 사이에 있는 이 ¹ CPU Cache Memory 와 ² 병렬성 이라는 특징으로 인해 다수의 스레드가 '공유자원'에 접근할 때 두 가지 문제가 발생할 수 있다.
위 두가지의 문제점에 대해 좀 더 이해해보고 해결방법을 찾아보자.
여러 개의 스레드가 사용됨에 따라, CPU Cache Memory와 RAM의 데이터가 서로 일치하지 않아 생기는 문제
CPU Cache Memory을 거쳐서 읽는게 아닌, RAM에서 바로 읽도록 보장해야 한다.
=> 변수에 valiatile 이라는 키워드를 붙여 가시성을 보장한다.
private static volatile boolean isStop;
volatile
키워드는 어디까지나 volatile 변수를 메인 메모리로부터 읽을 수 있게 해 주는 것이 전부이고, 다른 스레드에 의해 이 값이 언제든 바뀔 수 있다.=> 멀티 스레드 환경에서는 한 스레드가 각 기계 명령어를 수행하는 동안에 다른 스레드가 개입하여 공유 변수에 접근하여 같은 기계 명령어를 수행할 수 있으므로 값이 꼬이게 된다
synchronized
또는 atomic
을 사용
- 그리고 원자성 문제를 이 둘을 이용해 해결한다면 가시성 문제도 해결이 된다.
synchronized
블럭을 들어가기 전에 CPU Cache Memory
와 Main Memory를 동기화 해주며,atomic
의 경우에는 CAS 알고리즘에 의해 원자성 문제와 CPU Cache Memory에 잘못된 값을 참조하는 문제를 동시에 해결해주기 때문이다.멀티 스레드 환경에서 동시성 제어를 위해 공유 객체를 동기화하는 키워드이다. synchronized 블록 안에서 관리되는 자원들은 원자성을 보장할 수 있다.
멀티 스레드 환경에서 원자성을 보장하기 위해 나온 개념이다. 동기화(blockin)가 아닌 CAS(Compared And Swap)라는 알고리즘으로 작동하여 원자성을 보장한다.
+) CAS 알고리즘이란
CPU Cache Memory와 RAM을 비교하여 일치한다면 CPU Cache Memory와 RAM에 적용하고, 일치하지 않는다면 재시도 한다.
=> 어떠한 스레드에서 공유 자원에 읽기/쓰기 작업을 하더라도 원자성을 보장한다.
steady-coding님의 글을 참조하여 작성하였습니다.