s_y_130
About SY
s_y_130
전체 방문자
오늘
어제
  • 분류 전체보기
    • JAVA
      • 더 자바 8
      • JAVA
      • JAVA (JVM)
    • Computer Science
      • CS Basic
      • OOP
      • Design Pattern
      • Network
      • HTTP
      • WEB
      • OS
    • DataBase
      • DB theory
      • MySQL
      • Redis
    • Collection Framework
      • 구현
    • Data Structure
      • Linear
      • Non-Linear
    • Algorithm
      • Basic
      • 응용
      • 완전 탐색(Brute Force)
      • 다익스트라
      • Algorithm Problem
    • Spring
      • 스프링 핵심 원리 - 기본편
      • 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
      • 스프링 MVC 2편 - 백엔드 웹 개발 핵심 기술
      • 스프링 DB 1편 - 데이터 접근 핵심 원리
      • 스프링 DB 2편 - 데이터 접근 활용 기술
      • 스프링 핵심 원리 - 고급편
      • 스프링 부트 - 핵심 원리와 활용
      • 재고시스템으로 알아보는 동시성이슈 해결방법
      • 개념
      • 테스트
      • Annotation
      • Error Log
    • TEST
      • 부하 테스트
      • Practical Testing: 실용적인 테스트..
    • JPA
      • 자바 ORM 표준 JPA 프로그래밍
      • 1편- 실전! 스프링 부트와 JPA 활용
      • 2편- 실전! 스프링 부트와 JPA 활용
      • 실전! 스프링 데이터 JPA
      • 실전! Querydsl
      • 개념
    • Open Source
    • Book Study
      • Morden Java in Action
      • Real MySQL 8.0 Vol.1
      • TDD : By Example
    • AWS
      • EC2
    • git
    • AI
      • Machine Learning
      • Deep Learning
      • TensorFlow
      • PyTorch
      • YOLO
      • Data Analysis
      • Ai code Error
      • Numpy
    • MY
    • WEB
      • Django
      • WEB 개념
      • React
      • Maven
    • Python
    • 기초수학

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
s_y_130

About SY

JAVA/JAVA

[Java] volatile 키워드란?

2023. 7. 18. 15:16

이전 글에서는 가시성 문제를 해결하기 위해 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로 설정하기 때문에 backgroupThread는 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으로 직접 읽고 쓰는 작업을 수행하게 된다.

 

 

변경된 코드를 살펴보자.

public class Volatile {

    private static volatile 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초 후 프로그램이 종료되는 것을 확인할 수 있다.

 

 

 

예상 면접 질문 및 답변


Q. volatile 키워드에 대해 설명

동시성 프로그래밍에서 발생할 수 있는 문제 중 하나인 가시성 문제를 해결하기 위해 사용되는 키워드 이다. 가시성 문제는 여러 개의 스레드가 사용됨에 따라, CPU Cache Memory와 RAM의 데이터가 서로 일치하지 않아 생기는 문제를 의미한다. volatile 키워드를 붙인 공유 자원은 RAM에 직접 읽고 쓰는 작업을 수행할 수 있도록 해준다.

 

 

 

 


참고

  • https://badcandy.github.io/2019/01/14/concurrency-02/
  • https://ecsimsw.tistory.com/entry/자바의-동기화-방식-메모리-가시성이란-synchronized-volatile-atomic
    'JAVA/JAVA' 카테고리의 다른 글
    • Java 의 InterruptedException
    • [Java] synchronized 키워드란?
    • [JAVA] 자바의 동시성 이슈
    • [JAVA] 자바 NULL 에 관하여...
    s_y_130
    s_y_130

    티스토리툴바