Volatile는 뭘까??

Arakene·2025년 7월 7일

이전 Lazy에 대해서 알아볼 때, 그리고 이전부터 동시성이나 스레드 관련된 공부를 하다보면 한번씩 보이는 어노테이션이다.

어떤 역할을 할까?

멀티 스레드 프로그래밍 환경에서 멀티스레드 환경에서 변수의 가시성과 일관성을 보장하기 위해 사용된다. 아래는 어노테이션에 달린 주석이다.

Marks the JVM backing field of the annotated var property as volatile, meaning that reads and writes to this field are atomic and writes are always made visible to other threads. If another thread reads the value of this field (e.g. through its accessor), it sees not only that value, but all side effects that led to writing that value.
Note that only backing field operations are atomic when the field is annotated with Volatile. For example, if the property getter or setter make several operations with the backing field, a property operation, i.e. reading or setting it through these accessors, is not guaranteed to be atomic.

읽기와 쓰기 작업이 원자적으로(atomic)하게 수행되며, 어떤 스레드에서도 이 필드에 값을 쓰면 다른 스레드에서도 그 변경사항이 보이도록 보장된다.
라고한다.

잘 이해가 안되는데..

가시성이라고 하니 잘 이해가 안되는데 아래 예시를 보면서 이해를 해보자

// @Volatile
private var isStopped = false

fun startTask() {
    thread {
        while (!isStopped) {
            // Perform task
        }
    }
}

fun stopTask() {
    isStopped = true
}

만약 이 작업을 여러 스레드에서 생성해서 작업하는데 stopTask()를 호출하면 호출한 스레드만 멈추게 된다.
그 이유는 isStopped가 cpu에 캐싱이 되어 사용된다. 각 스레드가 참조하고 있는 캐싱값이 다르기 때문에 호출한 스레드만 작업이 끝나게 된다.

만약 주석처리된 @Volatitle을 해제하고 사용하면 isStopped을 캐싱하지 않고 메인 메모리에 있는 값을 사용하게 되기때문에 모든 스레드에서 값 변경을 감지하고 스레드가 모두 멈추게된다.

이제 이해된다! 정리하면

가시성은 변수의 참조를 어디를 보고있는지에 대한 말이다. 각각의 CPU에 캐싱된 값을 사용하지 않고 메인 메모리에 있는 값을 참조함으로써 가시성과 일관성을 보장한다는걸 이해했다.

profile
안녕하세요 삽질하는걸 좋아하는 4년차 안드로이드 개발자입니다.

0개의 댓글