본문 바로가기

프로그래밍 언어/Java

Java Volatile은 무엇이고 왜 필요할까?

Java Volatile이란?

  • volatile keyword는 Java 변수를 Main Memory에 저장하겠다라는 것을 명시하는 것이다. 
  • 그러므로 매번 Read/Write 작업을 할때 CPU Cache에 값을 저장하거나 읽는것을 넘어서 Main Memory영역까지 저장하고 읽는것을 의미한다.

그렇다면 왜 필요할까?

출처 : https://dev.to/rnowif/what-is-a-volatile-variable-in-java-35ef

위의 그림을 자세히 살펴보자. CPU는 중간에 Cache Memory를 경우하고 Main Memory에 접근한다. 왜 그럴까?

  • volatile 변수를 사용하고 있지 않는 MultiThread 어플리케이션에서는 Task를 수행하는 동안 성능 향상을 위해 Main Memory에서 읽은 변수 값을 CPU Cache에 저장하게 됩니다.
  • 만약에 Multi Thread환경에서 Thread가 변수 값을 읽어올 때 각각의 CPU Cache에 저장된 값이 다르기 때문에 변수 값 불일치 문제가 발생하게 됩니다.
public class counter {
    public int count;
}

위의 Case를 예시로 두고 설명해보자.

두개의 Thread가 있다고 가정하자.

첫번째는 Count를 더하고 읽는 작업을 수행하는 Thread1

두번째는 Count를 읽는 작업만 수행하는 Thread2

위와 같은 문제가 발생할수 있다.

Thread1은 count값을 증가시키지만 CPU Cache에만 반영되어 있고, Main Memory에는 저장을 하지 않아서 Thread2는 count = 0을 읽는 불상사가 발생할수 있습니다.

해결책

public class counter {
    public volatile int count;
}

다음과 같은 volatile keyword를 붙여서, 수행하게 되면 Main Memory에 저장하고 읽기 때문에 변수값 불일치 문제를 해결할수 있습니다.

그렇다면 언제 쓸까?

결론을 말하자면, 하나의 Thread만 Read하고 Write하는 환경에서 사용해야 합니다.

위와 같이 2개 이상의 Thread가 Read하고 Write하는 환경이라면, Count값의 불일치를 야기할수 있습니다.

위와 같은  상황일때는 원장성을 보장해야 하기 때문에, Java Synchronized keyword를 사용해야 합니다.

성능 이슈

  • volatile는 변수의 read와 write를 Main Memory에서 진행하게 됩니다.
  • CPU Cache보다 Main Memory가 비용이 더 크기 때문에 변수 값 일치을 보장해야 하는 경우에만 volatile 사용하는 것이 좋습니다.

정리

  • volatile
    • Main Memory에 read & write를 보장하는 키워드
    • 하나의 Thread가 write하고 나머지 Thread가 읽는 상황인 경우
    • 성능에 영향이 어느 정도 영향을 줄 수 있다라는 점

'프로그래밍 언어 > Java' 카테고리의 다른 글

jvm, jre, jdk 확실하게 구별하자  (0) 2022.07.28
enum과 활용사례  (0) 2022.07.13
접근제어자  (0) 2022.07.13
Hash Map과 Hash Collision 문제  (0) 2022.07.10
GC(Garbage Collector)  (0) 2022.07.10