volatile

2022. 5. 10. 10:32·자바/프로세스와 쓰레드

1. volatile

- 메모리 값과 캐시 값과의 차이가 발생할 때 volatile을 사용한다.

 

- 이 volatile은 싱글 코어 프로세서에서는 문제가 발생하지 않으므로 쓰일 곳이 없지만, 멀티 코어 프로세서에서

많이 쓰일 것이다. 그 이유는 멀티코어 프로세서마다 각 캐시가 존재하기 때문이다.

 

- 코어는 메모리에서 읽어온 값을 캐시에 저장하고 캐시에서 값을 읽어서 빠르게 작업한다. 그러다보니, 

값을 읽어올 때 캐시에 값이 존재하는지 확인하고 없을 때에만 메모리에 가서 값을 읽어온다. 

 

- 만약 코어가 메모리에 값이 변경되었는데도 캐시 값을 쓰인다면, 의도와 다른 값을 가질 수 있다.

 

- 그러나 캐시에 사용되는 변수 앞에 volatile을 쓴다면, 코어가 캐시가 아닌 메모리에 가서 읽어오기 때문에

해결할 수 있다.

 

- 추가적으로 synchronized 블럭을 사용해도 같은 효과를 얻을 수 있다. 그 이유는 캐시와 메모리간의 동기화가

이루어지기 때문에 값의 불일치가 해소되기 때문이다.

 

 

 

 

2. volatile로 long과 double을 원자화

- JVM은 데이터 처리를 4 byte단위로 처리하기 때문에, int와 int보다 작은 타입들은 한번에 읽거나 쓰는 것이

가능하다. 즉, 명령어를 쪼개거나 나눌 수 없는 최소의 작업단위라는 것이다. 그러므로, 다른 쓰레드가 끼어들 수 없다.

 

- 그러나 만약 long이나 doubl인 경우 8 byte이므로, 다른 쓰레드가 끼어들 여지가 있다. synchronized를

사용하여 메서드를 감싸서 처리할 수 있지만, 더 간단하게 volatile을 붙이면 된다.

( 단, 상수에는 붙일 수 없다. )

 

- volatile에서의 원자화란, 더 이상 작업을 나눌 수 없다는 뜻이다. 또한 synchronized 블럭도 일종의 원자화라고

볼 수 있다.

 

- 주의할 점은 volatile은 동기화를 하는 것은 아니다. 아래의 예제를 보자.

volatile long balance;
// balance를 원자화한다.

synchronized int getBalance(){
	return balance;
}

synchronized void withdraw(int money){
     if(balance >= money){
    	   balance -= money;
    }
}

 

( balance를 원자화 했기 때문에 getBalance를 동기화할 필요 없다고 생각할 수 있다. )

( 그러나 만약 withdraw(출금)을 실행하면 lock을 걸고 getBalance()를 호출할 수 있게 된다, )

( 그러므로, 출금이 진행중일 때는 기다렸다가 출금이 끝난 후에 잔고를 조회할 수 있게 해야한다. )

저작자표시 (새창열림)

'자바 > 프로세스와 쓰레드' 카테고리의 다른 글

fork & join 프레임웍  (0) 2022.05.10
쓰레드의 동기화(3): Lock과 Condition을 이용한 동기화  (0) 2022.05.08
쓰레드의 동기화(2): wait() & notify()  (0) 2022.05.07
쓰레드의 동기화(1): Critical Section & Lock, snychronized  (0) 2022.05.07
쓰레드의 실행제어  (0) 2022.02.20
'자바/프로세스와 쓰레드' 카테고리의 다른 글
  • fork & join 프레임웍
  • 쓰레드의 동기화(3): Lock과 Condition을 이용한 동기화
  • 쓰레드의 동기화(2): wait() & notify()
  • 쓰레드의 동기화(1): Critical Section & Lock, snychronized
백_곰
백_곰
  • 백_곰
    친절한 코딩
    백_곰
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 알고리즘 (with JAVA)
        • 기본 알고리즘
        • 완전 탐색
        • 분할 정복 알고리즘
        • 동적 계획법
        • 탐욕법
        • 코딩 테스트 기출 문제
        • 코드트리 조별과제
      • 백준 (with JAVA)
        • 완전 탐색
        • 분할 정복
        • 그 외
      • 자바
        • 개발 환경 구축하기
        • 팁
        • 기본적인 개념
        • 컬렉션 프레임워크
        • 프로세스와 쓰레드
        • 지네릭스
        • 람다식
        • 스트림
        • 입출력 IO
        • 네트워킹
        • 열거형(enums)
        • java.lang 패키지
        • java.time 패키지
        • 유용한 클래스들
        • 형식화 클래스들
      • 안드로이드 with 자바
        • 응용 문제들
        • 자잘한 문제들
        • 오류 보고서
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

      코딩트리조별과제
      snail
      역직렬화
      다형성
      제자리 정렬
      문자 기반 스트림
      InputStream
      유용한 클래스
      java.time 패키지
      선택 정렬
      중간연산
      람다식
      코드트리
      file
      자바 개념
      ServerSocket
      java.lang패키지
      소켓 프로그래밍
      안정 정렬
      outputstream
      알고스팟
      안드로이드 스튜디오
      serializable
      코딩테스트
      스트림
      TCP 소켓 프로그래밍
      Collections Framework
      map()
      불안정 정렬
      Arrays
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.3
    백_곰
    volatile
    상단으로

    티스토리툴바