volatile이란?

자바의 volatile 키워드 또는 코틀린의 @Volatile 애노테이션을 변수 선언시 지정할 수 있다. 사전적 의미로는 ‘휘발성의’라는 뜻을 가지며, 변수 선언시 volatile을 지정하면 값을 메인 메모리에만 적재하게 된다.

volatile 변수를 사용하지 않는 일반적인 경우는 내부적으로 성능 향상을 위해 메인 메모리로부터 읽어온 값을 CPU 캐시에 저장한다. 하지만 멀티쓰레드 애플리케이션에서는 각 쓰레드를 통해 CPU에 캐싱한 값이 상이할 수 있다 (CPU 캐시1 값 ≠ CPU 캐시2 값). 예제코드를 살펴보자

메인 메모리와 CPU캐시의 값이 다른 경우

다음과 같은 Thread를 확장한 서브 클래스가 있다고 가정하자.

class Worker : Thread() {
    var stop = false
    override fun run() {
        super.run()
        while(!stop){ }
    }
}

이 Worker 클래스는 단순히 무한루프에 빠지는 쓰레드다. 하지만 stop이 true가 되는 순간 루프에서 빠져나와 작업을 마칠 수 있게되고, 쓰레드는 종료된다.

이제 Worker 클래스를 사용한 다음 예제코드를 살펴보자.

@Test
fun `Worker 쓰레드 테스트`(){
    repeat(3){
        val worker = Worker() // worker 쓰레드 생성
        worker.start() // worker 쓰레드 시작
        Thread.sleep(100) // 메인 쓰레드 잠시 수면
        println("stop을 true로 변경")
        worker.stop = true // worker쓰레드의 stop 플래그 변경
        worker.join() // worker 쓰레드가 끝날 때까지 메인쓰레드에서 대기
    }
    println("작업 종료")
}

이 코드를 실행했을 때 직관적으로 생각할 수 있는 출력 메시지는 아마 다음과 같을 것이다.

stop을 true로 변경
stop을 true로 변경
stop을 true로 변경
작업 종료

하지만 현실은 그렇지 않다. “stop을 true로 변경” 메시지만 남긴 채 프로그램이 멈추게 된다.

그 이유는 Worker 쓰레드가 ‘stop’이란 값을 계속 참조해야 하기 때문에 성능을 위해 CPU 캐시에 담아두게 되는데, 이때 메인쓰레드에서 접근하는 worker.stop의 값은 메인 메모리로부터 참조하는 값이므로 서로 다른 두개의 영역에 값이 존재한다. 메인스레드에서 stop을 true로 바꿔도 Worker 쓰레드가 참조하는 stop은 CPU 캐시 영역에 저장된 값이므로 여전히 stop은 false이다. 그렇기 때문에 Worker 쓰레드는 루프를 빠져나오지 못하고 프로그램은 멈추게 된다.

이제 코드를 약간 수정해보자. 수정은 매우 간단하다. @Volatile 만 붙이면 된다.

class Worker : Thread() {
    @Volatile
    var stop = false
    override fun run() {
        super.run()
        while(!stop){ }
    }
}

이제 아까 테스트 코드를 다시 수행하면 기대한 결과를 얻을 수 있다.

결론

@Volatile을 붙이면 변수의 값이 메인 메모리에만 저장되며, 멀티 쓰레드 환경에서 메인 메모리의 값을 참조하므로 변수 값 불일치 문제를 해결할 수 있게된다. 다만 CPU캐시를 참조하는 것보다 메인메모리를 참조하는 것이 더 느리므로, 성능은 떨어질 수 밖에 없다.

참조 링크

http://tutorials.jenkov.com/java-concurrency/volatile.html

https://codingdog.tistory.com/entry/java-volatile-%EB%B3%80%EC%88%98%EC%9D%98-%EA%B0%80%EC%8B%9C%EC%84%B1%EA%B3%BC-%EC%B5%9C%EC%A0%81%ED%99%94


후원하기

카테고리: Kotlin

2개의 댓글

김정원 · 2022년 3월 17일 10:38 오전

Volatile에 대해 잘 몰랐는데 쉽고 명확하게 알고 갑니다!
감사합니다

    Charlezz · 2022년 3월 22일 6:13 오후

    ㅎㅎㅎ 감사합니다

답글 남기기

Avatar placeholder

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.