JAVA의 동시성 이슈

MINJU·2022년 8월 21일
0

Java

목록 보기
6/7

참조 블로그

CPU가 작업을 처리하기 위해 데이터가 필요할 때, CPU는 RAM의 일부분을 (고속 저장장치인) CPU Cache Memory로 읽어들입니다. 또한 RAM에 저장하기 위해서는 데이터를 우선 CPU Cache Memory에 쓴 다음 RAM에 쓰기 작업을 수행합니다. 하지만 Cache에 쓰기 작업을 수행했다고 해서, 바로 RAM으로 쓰기 작업을 수행하진 않습니다. 이는 반대 과정인 읽기 작업도 마찬가지입니다.

이와 같이 CPU와 Ram의 중간에 위치하는 CPU Cache Memory와 병렬성이라는 특징 때문에 다수의 스레드가 공유 자원에 접근할 때 두 가지 문제가 발생할 수 있습니다.

  • 가시성 문제
  • 원자성(동시 접근) 문제

- 가시성 문제

여러 개의 스레드가 사용됨에 따라 CPU Cache Memory와 RMA의 데이터가 서로 일치하지 않아 생기는 문제를 의미합니다. 이를 해결하기 위해서는 "가시성이 보장되어야 하는 변수"를 RAM에서 바로 읽도록 보장해야합니다.

이때 변수에 volatile 키워드를 붙임으로서 가시성을 보장할 수 있습니다.

private static volatile boolean isStop;

하지만 가시성이 보장된다고 -> 동시성이 보장되는 것은 아닙니다.

참조 블로그에서의 예시를 들어보겠습니다.

"전철 비용"을 계산하는 프로그램을 작성한다고 가정해봅시다. 나이에 따라 70세 미만과 이상의 표 값이 다른 상황이고, 날짜를 실시간으로 반영하여 비용을 계산해야합니다. 각 스레드의 역할은 다음과 같습니다.

스레드1

  • 고객의 나이 읽음
  • 읽은 나이 기준 비용 계산
  • 비용 반환

스레드2

  • 현재 년도 지속적으로 읽음
  • 해가 바뀌면 고객의 나이를 계산
  • 바뀐 고객의 나이를 저장

이때 volatile을 사용하면 가시성을 해결할 순 있겠지만, 해가 바뀌는 시점에 문제가 발생합니다.

나이가 69세인 고객이 계산을 진행할 때, "스레드1"에서는 RAM에서 나이가 69세임을 가져와서 그 나이에 따라 비용을 계산합니다. 그러나 마침 해가 딱 바뀌어 "스레드2"에서 RAM에 해당 고객의 나이를 70살로 수정한다고 해봅시다. 이 경우 "스레드1"은 나이가 70세로 바뀐 것을 모르고 69세를 기준으로 비용을 계산하게 되고 이로 인해 잘못된 비용을 반환하게 됩니다.

이러한 예제에서 살펴볼 수 있듯 volatile 키워드는 변수를 메인 메모리로부터 읽을 수 있게 해주는 것이 전부입니다. 다른 스레드에 의해 이 값은 언제든지 바뀔 수 있습니다. 즉, 가시성이란 공유 데이터를 읽는 경우의 동시성만 보장하는 것이라 생각하면 됩니다.

✔ 원자성 문제

원자성은 "멀티 스레드 환경에서 스레드간 공유 메모리 이슈"를 발생한다는 점에서 공통점이 있습니다. 하지만 시스템 관점에서 보면 두 개념은 다릅니다.

[ 가시성 ] = CPU-Cache-Memory 관계상의 개념
[ 원자성 ] = 한 줄의 프로그램 문장이 컴파일러에 의해 기계어로 번역되면서 이를 기계가 순차적으로 처리하기 위한 여러개의 Machine Instruction이 만들어져 실행되기 때문에 일어나는 현상. 에를 들어 i++ 문장은 (i를 메모리로부터 읽고)+(읽은 값에 1을 더하고)+(연산한 값을 메모리에 저장)하는 세 개의 기계가 수행하는 명령어로 쪼개지게 되는데, 멀티스레드 환경에서는 한 스레드가 각 기계 명령어를 수행하는 동안에 다른 스레드가 개입하여 공유 변수에 접근하여 같은 기계 명령어를 수행할 수 있으므로 값이 꼬이게 되는 것입니다.

원자성 문제를 해결하기 위해서는 synchronized 또는 atomatic을 사용해야합니다.

synchronized나 atomatic을 통해 원자성을 해결한다면 가시성의 문제도 해결됩니다. synchronized 블럭에 들어가기 전에 CPU Cache Memory와 main Memory를 동기화 해주고, atomatic의 경우엔 알고리즘에 의해 원자성 문제 + CPU Cache Memory에 잘못된 값을 참조하는 문제를 동시에 해결해주기 때문.

0개의 댓글