Java/Concurrency

Java > Concurrency > 6. Memory visibility

Krevis 2024. 9. 13. 07:50

메모리 가시성

멀티 쓰레드 환경에서 한 쓰레드가 변경한 값이 다른 쓰레드에게 언제, 어떻게 보여지는지에 대한 문제를 말한다

여러 쓰레드가 공유된 하나의 메모리에 접근할 때 이 문제가 발생한다

 

volatile 키워드를 사용해 문제를 해결할 수 있다

https://github.com/venzersiz/learn-java8/blob/master/src/test/java/concurrency/basic/ThreadVolatileTest.java

 

쓰레드 동기화 기법을 사용할 수도 있다

https://github.com/venzersiz/learn-java8/tree/master/src/test/java/concurrency/synchorize

 

 

Java Memory Model

여러 쓰레드들이 메모리를 공유하고 상호작용하는 것을 정의

 

동시성 프로그램을 올바르게 설계하고 싶다면 이 부분을 잘 이해하는 것이 중요하다

 

핵심은 Happens-before 관계에 대한 정의다

 

추후 학습 대상

Happens-before 관계

자바 메모리 모델에서 쓰레드 간의 작업 순서를 정의한다

 

A 작업이 B 작업에 Happens-before 관계에 있다면, A 작업에서 변경된 내용은 B 작업이 시작되기 전에 메모리에 반영된다

 

Read field, Write field, Lock, Unlock, Start, Join 등의 연산들은 다른 연산들 이전에 실행된다고 한다

 

이 규칙을 따르면 개발자가 멀티 쓰레드 프로그램을 작성할 때 예상치 못한 동작을 피할 수 있다

Happens-before 관계가 발생하는 경우

암기하지 말고 자연스럽게 이해하면 된다

 

  • 프로그램 순서 규칙
  • volatile 변수 규칙
    • 한 쓰레드에서 volatile 변수에 대한 쓰기 작업은 해당 변수를 읽는 다른 쓰레드에게 보이게 한다
  • 쓰레드 시작 규칙
    • start() 메서드 호출 전의 코드가 먼저 실행된다
  • 쓰레드 종료 규칙
    • 대상 쓰레드의 join() 메서드를 호출하면 대상 쓰레드의 작업이 우선한다
  • 인터럽트 규칙
    • interrupt() 메서드를 호출하는 작업이 대상 쓰레드가 자신의 interrupted 상태를 확인하는 작업보다 우선한다
  • 객체 생성 규칙
    • 객체의 생성자에서 초기화된 필드는 생성자 완료 후 다른 쓰레드에서 참조된다
  • 모니터 락 규칙
    • synchronized 블락이나 ReentrantLock처럼 락을 사용하는 작업은 우선한다
  • 전이(Transitivity) 규칙
    • A가 B보다 우선하고 B가 C보다 우선하면 A는 C보다 우선한다

 

 

참고