자바 volatile 은 어떻게 금지 명령 의 재배 치 를 실현 합 니까?
소스 코드->컴 파 일 러 최적화 정렬->명령 병렬 정렬->메모리 시스템 정렬->최종 실행 명령
단일 스 레 드 환경 에서 최종 실행 결과 와 코드 순서 가 일치 하도록 확보 합 니 다.
프로세서 가 재 정렬 을 할 때 는 명령 간 의 데이터 의존 도 를 고려 해 야 한다.
다 중 스 레 드 환경 에서 스 레 드 교체 가 실 행 됩 니 다.컴 파일 러 의 최적화 재배 치 존재 로 인해 두 스 레 드 에서 사용 하 는 변수 가 일치 성 을 확보 할 수 있 는 지 는 확실 하지 않 고 결 과 는 예측 할 수 없습니다.
명령 어 정렬-example 1
public void mySort() {
int x = 11;
int y = 12;
x = x + 5;
y = x * x;
}
정상 적 인 단일 스 레 드 환경 에 따라 실행 순 서 는 1,2,3,4 입 니 다.그러나 다 중 스 레 드 환경 에서 다음 과 같은 순서 가 나타 날 수 있 습 니 다.
2 1 3 4
1 3 2 4
상기 과정 은 명령 의 재 배열,즉 내부 집행 순서 로 우리 의 코드 순서 와 다르다 고 볼 수 있다.
그러나 명령 의 재배 열 도 제한 이 있다.즉,아래 순서 가 나타 나 지 않 는 다 는 것 이다.
4 3 2 1
프로세서 가 재배 열 을 진행 할 때 명령 간 의 데이터 의존 도 를 고려 해 야 하기 때문이다.
절차 4:y 의 설명 과 x 의 설명 에 의존 해 야 하기 때문에 데이터 의존 이 존재 하기 때문에 먼저 실행 할 수 없습니다.
예시
int a,b,x,y = 0
스 레 드 1
스 레 드 2
x = a;
y = b;
b = 1;
a = 2;
x = 0; y = 0
위의 코드 는 데이터 의 의존성 이 존재 하지 않 기 때문에 컴 파일 러 는 데 이 터 를 다시 배열 할 수 있 습 니 다.
스 레 드 1
스 레 드 2
b = 1;
a = 2;
x = a;
y = b;
x = 2; y = 1
이렇게 된 결 과 는 처음 과 일치 하지 않 는 다.이것 이 바로 재배 치 후 결과 가 처음 과 다 르 기 때문에 이런 결 과 를 방지 하기 위해 volatile 은 명령 재배 치 를 금지 하고 데이터 의 일치 성 을 확보 하도록 규정 했다.
명령 어 정렬-example 2
예 를 들 어 아래 코드.
public class ResortSeqDemo {
int a= 0;
boolean flag = false;
public void method01() {
a = 1;
flag = true;
}
public void method02() {
if(flag) {
a = a + 5;
System.out.println("reValue:" + a);
}
}
}
우 리 는 정상 적 인 순서에 따라 각각 method 01()과 method 02()를 호출 합 니 다.그러면 최종 출력 은 a=6 입 니 다.그러나 다 중 스 레 드 환경 에서 방법 1 과 방법 2 로 인해 데이터 의존 문제 가 존재 하지 않 기 때문에 원래 의 순 서 는?
a = 1;
flag = true;
a = a + 5;
System.out.println("reValue:" + a);
그러나 컴 파일 러,명령,또는 메모리 의 재배 치 를 거 친 후에 이런 상황 이 발생 할 수 있다.
flag = true;
a = a + 5;
System.out.println("reValue:" + a);
a = 1;
즉,flag=true 를 먼저 실행 한 후,다른 스 레 드 는 즉시 호출 방법 2,flag 의 판단 을 만족 시 키 고,최종 적 으로 a+5,결 과 는 5 로 데이터 가 일치 하지 않 는 문제 가 발생 합 니 다.
왜 이런 결과 가 나 왔 는 지:다 중 스 레 드 환경 에서 스 레 드 교체 가 실 행 됩 니 다.컴 파일 러 가 최적화 되 어 재배 치 되 는 존재 로 인해 두 스 레 드 에서 사용 하 는 변수 가 일치 성 을 확보 할 수 있 는 지 는 확실 하지 않 고 결 과 는 예측 할 수 없습니다.
이렇게 하려 면 volatile 을 통 해 수식 하여 라인 의 안전성 을 확보 해 야 한다
Volatile 은 명령 어 를 정렬 하기 위해 무엇 을 했 습 니까?
Volatile 은 금지 명령 의 재배 치 최 적 화 를 실현 하여 다 중 스 레 드 환경 에서 프로그램 이 무질서 하 게 실행 되 는 현상 을 피 했다.
먼저 하나의 개념 을 알 아 보 세 요.메모리 장벽(Memory Barrier)은 메모리 울타리 라 고도 부 르 는데 CPU 명령 입 니 다.그 역할 은 두 가지 가 있 습 니 다.
특정 작업 의 순 서 를 확보 하여 일부 변수의 메모리 가시 성 을 확보 합 니 다(이 특성 을 이용 하여 volatile 의 메모리 가시 성 을 실현 합 니 다)
컴 파 일 러 와 프로세서 가 명령 정렬 의 최 적 화 를 실행 할 수 있 기 때문에 명령 키 에 Memory Barrier 를 삽입 하면 컴 파 일 러 와 CPU 에 어떤 명령 도 이 Memory Barrier 명령 과 정렬 할 수 없다 고 알려 줍 니 다.즉,메모리 장벽 을 삽입 한 전후의 명령 을 통 해 정렬 을 최적화 할 수 있 습 니 다.메모리 장벽 의 또 다른 역할 은 각종 CPU 의 캐 시 수 를 새로 고 치 는 것 이기 때문에 모든 cpu 의 스 레 드 에서 이 데이터 의 최신 버 전 을 읽 을 수 있 습 니 다.
즉,Volatile 의 쓰기 와 읽 기 를 할 때 장벽 을 넣 어 명령 의 재배 치 라인 이 안전하게 보장 되 는 것 을 방지 하 는 것 이다.
작업 메모리 와 메 인 메모리 의 동기 화 지연 현상 으로 인 한 가시 적 문제
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.