2022. 8. 25. 16:32ㆍJava
Java에서는 가시성 문제를 해결하기 위해 volatile 키워드를 사용하게 된다. 이번 글에서는 volatile 키워드를 통해 가시성을 보장하는 방법을 간단한 예시와 함께 알아보자.
가시성을 보장하지 못한 예제
public class Volatile {
private static boolean stopRequested;
public static void main(String[] args) throws InterruptedException {
Thread backgroundThread = new Thread(() -> {
int i = 0;
while (!stopRequested) {
i++;
}
});
backgroundThread.start();
Thread.sleep(1000);
stopRequested = true;
}
}
메인 스레드가 1초 후 stopRequested 변수를 true로 설정하기 때문에 backgroundThread는 1초 후 반복문을 빠져나올 수 있을 것처럼 보인다. 그러나 실제로 실행하면 위 코드는 아래처럼 반복문을 오랜 시간 빠져 나오지 못하거나, 기타 다른 요인이 더 추가되면 영원히 못 나올 수도 있다.
가시성 문제가 발생한 원인과 해결 방법
CPU 1에서 수행된 스레드를 backgroundThread, CPU 2에서 수행된 스레드를 mainThread라고 하자.
mainThread는 CPU Cache Memory 2와 RAM에 공유 변수인 stopRequested를 true로 쓰기 작업을 완료하였으나, backgroundThread는 CPU Cache Memory 1에서 읽은 업데이트 되지 않은 stopRequested 값을 사용한다.
이 값은 false이므로 계속해서 반복문을 수행하게 된다. 즉, mainThread가 수정한 값을 backgroundThread가 언제 보게 될지 보증할 수 없고 이러한 문제를 가시성 문제라고 한다.
이 문제를 해결하기 위해서는 stopRequested 변수를 volatile로 선언하면 된다. 그럼 다음 그림과 같이 CPU Cache Memory를 거치지 않고, RAM으로 직접 읽고 쓰는 작업을 수행하게 된다.
Volatile을 사용한 코드
public class Volatile {
private static volatile boolean stopRequested;
public static void main(String[] args) throws InterruptedException {
Thread backgroundThread = new Thread(() -> {
System.out.println("background start : " + System.currentTimeMillis());
int i = 0;
while (!stopRequested) {
i++;
}
System.out.println("background end : " + System.currentTimeMillis());
});
backgroundThread.start();
Thread.sleep(1000);
stopRequested = true;
}
}
// 출력
background start : 1661412632522
background end : 1661412633526
코드를 실행하면 1초 후 loop를 빠져나오는 것을 확인할 수 있다.
[출처]
https://steady-coding.tistory.com/555
[Java] volatile 키워드란?
java-study에서 스터디를 진행하고 있습니다. 이전 글에서는 가시성 문제를 해결하기 위해 volatile 키워드를 사용한다고 하였다. 이번 글에서는 volatile 키워드를 통해 가시성을 보장하는 방법을 간
steady-coding.tistory.com
'Java' 카테고리의 다른 글
[Java] synchronized 키워드 (0) | 2022.08.26 |
---|---|
[Java] Java의 동시성 이슈 (0) | 2022.08.25 |
[Java] Stream API의 고급 활용 및 사용 시 주의점 - 4/5 (0) | 2022.08.25 |
[Java] 람다식과 함수형 인터페이스 - 2/5 (0) | 2022.08.24 |
[Java] Stream API에 대한 이해 - 1/5 (0) | 2022.08.24 |