(Java) 자바 메모리 모델

* Java의 메모리 모델이란 Java의 쓰레드가 메모리에 액세스 할 떄 어떤 일이 일어나는지 규정하는 것이다.

* 자바 메모리 모델과 친해지기 위한 지침

  • 복수 쓰레드에서 공유하는 필드는 synchronized 또는 volatile로 보호하라
  • 불변 필드는 final하라
  • 생성자안에서 this를 놓치지 말라
1. reorder
2. visibility
3. 공유메모리와 액션
4. synchronized
5. volatile
6. final
7. Double-Checked Locking 패턴


1.  reorder

-> reoreder란 최적화를 위해 컴파일이나 Java 가상머신이 프로그램의 처리순서를 바꾸는 것을 말한다. reorder는 수행능려을 높이는데 널리 사용되지만 그 사실을 프로그래머가 의식하는 경우는 거의 없다. 실제 싱글 쓰레드 프로그램에서는 reorder가 이뤄지고 있는지 판단할 수 없다. 그러나 멀티쓰레드 프로그램에서는 reorder가 원인이 되어 이상 작동을 하는 경우가 있다.

자바의 컴파일러는 자바 코드를 바이트 코드로 컴파일 하면서 정해진 범위 내에서 자유롭게 최적화를 수행할 수 있다. 이런 최적화에는 단순히 코드의 특정 구문을 보다 효율적인 다른 구문으로 치환하는 경우도 있지만, 때론 중복된 구문을 삭제하거나 구문 간의 순서를 재배치함으로써 소기의 목적을 달성하기도 한다. 뿐만 아니라 CPU의 연산 시에도 인스트럭션을 재배열하거나 보다 작은 마이크로 인스트럭션으로 나눠서 처리할 수도 있기 때문에 자바로 작성된 프로그램의 정확한 수행 순서를 예측하기란 쉽지가 않다. 자바는 앞서 설명한 happens-before 관계를 보장함으로써 일반적인 단일 스레드 환경에서의 수행 순서를 보장하고 있지만, 멀티스레딩 환경에선 최적화에 따른 재배열(reordering)이 예상치 못한 가시성의 문제를 일으키지 않도록 보장하기 위해 명시적으로 동기화를 처리해 happens-before 관계를 분명히 밝혀야 한다.



->쓰기 쓰레드와 읽기 쓰레드가 분리되어 있고 x대입문 뒤에 y 대입문이 적혀있기 때문에
x가 먼저 0에서 100으로 커지고 y가 0에서 50으로 커지겠다는 생각이 듭니다.
하지만 x < y 로 표시될 가능성이 있다. 그 이유는 reorder때문이다.
write메소드 안에서 x에 대한 대입과 y에 대한 대입사이에는 의존관계가 없기 때문이다. 

이 예처럼 [쓰기쓰레드]와 [읽기쓰레드]가 존재함에도 불구하고 그 필드가 synchronized 나 volatile 로  정상적으로 동기화 되지 않은 상태를 "데이터레이스"가 있다고 말한다.



2. visibility 란

-> 쓰레드 A가 x에 입력한 내용을 쓰레드 B에서 읽을 수 있는 것.



3. 공유 메모리와 액션

Java 메모리 모델에서는 쓰레드 A가 입력한 값을 쓰레드 B가 항상 곧바로 볼 수 있는 것은 아니다. 공유메모리는 모든 쓰레드가 공유하고 있는 기억영역으로, 힙 메모리라고도 합니다.
인스턴스는 모두 공유메모리에 확보되기 때문에 인스턴스가 가지고 있는 필드는 공유 메모리 상에 존재합니다. 또한 배열의 요소도 공유 메모리상에 확보된다. 즉, new를 사용하면 공유 메모리에 영역이 확보된다.


댓글

이 블로그의 인기 게시물

(18장) WebSocekt과 STOMP를 사용하여 메시징하기

(네트워크)폴링방식 vs 롱 폴링방식

(ElasticSearch) 결과에서 순서 정렬