Java의 Volatile은 Read Committed와 유사하다.

준하·2025년 5월 4일
0

Java에서 동시성(concurrency)을 다루는 방법은 크게 세가지가 존재한다.

  1. synchronized
  2. volatile
  3. Atomic

Volatile

이 중 volatile은 다른 스레드의 변경 사항에 대한 가시성(Visibility)을 확보시켜 준다.
하지만 원자성을 보장하지 않기 때문에, 동시성 문제를 완전히 해결할 수 없다.

메모리 계층 구조에서 CPU 코어와 메인메모리 사이에는 캐시가 존재한다.

프로세서의 발전속도를 메인메모리가 따라가지 못하면서,
CPU와 메인메모리 사이의 속도 간극을 줄여주는 완충제 역할을 위해 캐시를 도입한 것이다.

멀티코어 환경에서는 각 CPU 코어 별로 캐시메모리가 존재한다.

즉, 멀티스레딩 시 서로 다른 스레드가 서로 다른 코어에서 실행되면,
서로 다른 캐시를 사용하게 될 수 있다.

이로인해 메모리 가시성 문제(다른 스레드의 변경 사항이 보이지 않음)가 발생하며, 이를 해결하기 위해 volatile을 사용할 수 있다.

volatile은 JVM이 해당 변수의 읽기/쓰기를 항상 메인메모리 기준으로 강제한다.
즉, 어떤 스레드든 캐시된 값이 아닌, 최신 값을 공유하도록 보장한다.


Read Committed 와의 유사성

트랜잭션 격리 수준 중 Read Committed은 커밋된 다른 트랜잭션의 변경사항을 볼 수 있게 해준다.

하지만, 그것만으로 쓰기 작업에 대한 동시성 문제를 해결할 수 없다.

읽기 -> (다른 트랜잭션의 쓰기 커밋) -> 읽은 값에 기반한 쓰기

위와 같은 시나리오에서 동시성 문제가 발생하고, Read Committed 만으로는 해결이 불가능하며, 별도의 락킹 메커니즘이 필요하다.

마찬가지로, volatile은 다른 스레드의 변경 사항에 대한 가시성은 확보할 수 있으나,
복합 연산을 불가분한 연산으로 만들지 못하므로, 동시성 문제를 완벽히 해결할 수 없다.


Volatile만으로 동시성 문제를 해결하려면?

Read Only, Write Only 스레드를 나누어야 한다.

  • Read 작업은 여러 스레드에서 동시에 가능
  • Write 작업은 오직 하나의 스레드에서만!
profile
A Sound Code in a Sound Body💪

0개의 댓글