자바 volatile 은 어떻게 금지 명령 의 재배 치 를 실현 합 니까?

3699 단어 자바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 의 쓰기 와 읽 기 를 할 때 장벽 을 넣 어 명령 의 재배 치 라인 이 안전하게 보장 되 는 것 을 방지 하 는 것 이다.
작업 메모리 와 메 인 메모리 의 동기 화 지연 현상 으로 인 한 가시 적 문제
  • synchronized 나 volatile 키 워드 를 사용 하여 해결 할 수 있 습 니 다.한 스 레 드 가 수 정 된 변 수 를 다른 스 레 드 에 즉시 볼 수 있 습 니 다
  • 4.567917.명령 의 재배 치 로 인 한 가시 적 문제 와 질서 적 문제
  • volatile 키 워드 를 이용 하여 해결 할 수 있 습 니 다.volatile 의 또 다른 역할 은 정렬 최적화 금지 이기 때 문 입 니 다
  • 이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기