자바 메모리 모델 에 대한 happens-before

happens-before 원칙 은 매우 중요 하 다.이것 은 데이터 에 경쟁 이 존재 하 는 지,라인 이 안전 한 지 를 판단 하 는 주요 한 근거 이다.이 원칙 에 따라 우 리 는 병발 환경 에서 두 조작 사이 에 충돌 이 존재 할 수 있 는 모든 문 제 를 해결한다.다음은 간단 한 예 를 들 어 happens-before 에 대해 알 아 보 겠 습 니 다.i = 1;       // A
j = i ;      // B
j 는 1 입 니까?스 레 드 A 의 조작(i=1)happens-before 스 레 드 B 의 조작(j=i)을 가정 하면 스 레 드 B 가 실 행 된 후 j=1 이 반드시 성립 되 는 것 을 확정 할 수 있 습 니 다.만약 에 그들 이 happens-before 원칙 이 존재 하지 않 는 다 면 j=1 이 반드시 성립 되 는 것 은 아 닙 니 다.이것 이 바로 happens-before 원칙 의 위력 이다.
happens-before 원칙 의 정 의 는 다음 과 같다.
1.만약 에 하나의 조작 happens-before 가 다른 조작 을 한다 면 첫 번 째 작업 의 실행 결 과 는 두 번 째 작업 에 대해 볼 수 있 고 첫 번 째 작업 의 실행 순 서 는 두 번 째 작업 전에 배열 된다.
2.두 조작 사이 에 happens-before 관계 가 존재 하 는 것 은 반드시 happens-before 원칙 에 따라 제 정 된 순서에 따라 집행 해 야 한 다 는 것 을 의미 하지 않 는 다.정렬 을 다시 한 후의 실행 결과 가 happens-before 관계 에 따라 실 행 된 결과 와 일치 하면 이러한 정렬 은 불법 이 아니다.
다음은 happens-before 원칙 규칙 입 니 다.
1.프로그램 순서 규칙:한 스 레 드 에서 코드 순서에 따라 앞 에 쓰 는 작업 은 먼저 뒤에 쓰 는 작업 에서 발생 합 니 다.
2.잠 금 규칙:하나의 unLock 작업 은 다음 에 같은 잠 금 액 lock 작업 에서 먼저 발생 합 니 다.
3.volatile 변수 규칙:변수 에 대한 쓰기 동작 은 다음 변수 에 대한 읽 기 동작 에서 먼저 발생 합 니 다.
4.전달 규칙:만약 에 조작 A 가 조작 B 에서 먼저 발생 하고 조작 B 가 조작 C 에서 먼저 발생 하면 조작 A 가 조작 C 에서 먼저 발생 한 다 는 것 을 알 수 있다.
5.스 레 드 시작 규칙:Thread 대상 의 start()방법 은 이 스 레 드 의 모든 동작 에서 먼저 발생 합 니 다.
6.스 레 드 인 터 럽 트 규칙:스 레 드 인 터 럽 트()방법 에 대한 호출 은 인 터 럽 트 된 스 레 드 코드 에서 인 터 럽 트 사건 의 발생 을 먼저 감지 합 니 다.
7.스 레 드 종료 규칙:스 레 드 의 모든 작업 은 스 레 드 의 종료 검 측 에서 먼저 발생 합 니 다.우 리 는 Thread.join()방법 으로 끝 날 수 있 습 니 다.Thread.isAlive()의 반환 값 수단 으로 스 레 드 가 종료 되 었 음 을 감지 할 수 있 습 니 다.
8.대상 종료 규칙:한 대상 의 초기 화 완료 가 그의 finalize()방법의 시작 에서 먼저 발생 합 니 다.
우 리 는 위의 모든 규칙 을 상세 하 게 살 펴 보 자.
  • 프로그램 순서 규칙:코드 가 단일 스 레 드 에서 실 행 된 결 과 는 질서 가 있 습 니 다.가상 컴퓨터,프로세서 가 명령 을 다시 정렬 하기 때문에 실행 결과 에 주의 하 십시오.정렬 을 다시 했 지만 프로그램의 실행 결과 에 영향 을 주지 않 기 때문에 프로그램의 최종 실행 결 과 는 순서대로 실 행 된 결과 와 일치 합 니 다.따라서 이 규칙 은 단일 스 레 드 에 만 효과 가 있 고 다 중 스 레 드 환경 에서 정확성 을 보장 할 수 없다.
  • volatile 변수 규칙:이것 은 비교적 중요 한 규칙 으로 volatile 이 스 레 드 의 가시 성 을 확보 했다 는 것 을 상징 한다.통속 적 으로 말 하면 만약 에 한 라인 이 먼저 volatile 변 수 를 쓰 고 한 라인 이 이 변 수 를 읽는다 면 이 쓰기 동작 은 반드시 happens-before 읽 기 동작 일 것 이다.
  • 전달 규칙:happens-before 원칙 이 전달 성 을 가 진 다 는 것 을 제시 했다.즉,A happens-before B,B happens-before C,그러면 A happens-before C
  • 스 레 드 시작 규칙:스 레 드 A 가 실행 과정 에서 ThreadB.start()를 실행 하여 스 레 드 B 를 시작 하면 스 레 드 A 가 공유 변수 에 대한 수정 은 다음 스 레 드 B 가 실 행 된 후에 스 레 드 B 를 볼 수 있 도록 합 니 다.
  • 스 레 드 종료 규칙:스 레 드 A 가 실행 하 는 과정 에서 ThreadB.join()을 제정 하여 스 레 드 B 가 종 료 될 때 까지 스 레 드 B 가 종료 되 기 전에 공유 변수 에 대한 수정 은 스 레 드 A 가 돌아 오 기 를 기다 린 후에 볼 수 있 습 니 다.
  • 위의 8 가 지 는 원생 자바 가 Happens-before 관 계 를 만족 시 키 는 규칙 이지 만 우 리 는 그들 에 게 happens-before 를 만족 시 키 는 다른 규칙 을 유도 할 수 있다.
    1.라인 이 안전 한 대기 열 에 원 소 를 넣 는 동작 Happens-Before 대기 열 에서 이 원 소 를 꺼 내 는 동작
    2.스 레 드 보안 용기 에 원 소 를 넣 는 작업 Happens-Before 용기 에서 이 요 소 를 꺼 내 는 작업
    3.Countdown Latch 에서 의 마지막 동작 Happens-Before Countdown Latch\#await()동작
    4.Semaphore 허 가 를 받 은 조작 Happens-Before 허가 획득
    5.Future 가 표시 하 는 모든 작업 Happens-Before Future\#get()작업
    6.Executor 에 Runnable 또는 Callable 작업 을 제출 합 니 다.Happens-Before 작업 을 시작 합 니 다.
    여기 서 happens-before 의 개념 을 다시 한 번 말씀 드 리 겠 습 니 다.만약 에 두 조작 이 상기(앞의 8 개+뒤의 6 개)중 하나의 happens-before 규칙 이 존재 하지 않 는 다 면 이 두 조작 은 순서 적 인 보장 이 없고 JVM 은 이 두 조작 을 다시 정렬 할 수 있 습 니 다.A happens-before 조작 B 를 조작 하면 A 가 메모리 에서 하 는 조작 은 조작 B 에 대해 모두 볼 수 있 습 니 다.
    다음은 간단 한 예 를 들 어 happens-before 원칙 을 설명 한다.
    
    private int i = 0;
    
    public void write(int j ){
     i = j;
    }
    
    public int read(){
     return i;
    }
    
    우 리 는 스 레 드 A 가 write()를 실행 하고 스 레 드 B 가 read()를 실행 하 며 스 레 드 A 가 스 레 드 B 보다 우선 하 는 것 을 약속 합 니 다.그러면 스 레 드 B 가 얻 은 결 과 는 무엇 입 니까?우 리 는 이 간단 한 코드 에 대해 happens-before 의 규칙(규칙 5,6,7,8+유도 6 개 는 무시 할 수 있 습 니 다.왜냐하면 그들 은 이 코드 와 아무런 관계 가 없 기 때 문 입 니 다)을 분석 할 수 있 습 니 다.
    1.두 가지 방법 은 서로 다른 라인 에서 호출 되 기 때문에 프로그램의 순서 규칙 을 만족 시 키 지 못 할 것 이다.
    2.두 가지 방법 모두 자 물 쇠 를 사용 하지 않 았 기 때문에 잠 금 규칙 에 만족 하지 않 습 니 다.
    3.변수 i 는 volatile 로 수식 한 것 이 아니 기 때문에 volatile 변수 규칙 이 만족 하지 않 습 니 다.
    4.전달 규칙 은 만족 하지 않 을 것 이다.
    그래서 우 리 는 happens-before 원칙 을 통 해 스 레 드 A happens-before 스 레 드 B 를 유도 할 수 없습니다.시간 적 으로 스 레 드 A 가 스 레 드 B 보다 우선 하 는 지 확인 할 수 있 지만 스 레 드 B 가 얻 은 결과 가 무엇 인지 확인 할 수 없 기 때문에 이 코드 는 스 레 드 가 안전 하지 않 습 니 다.그럼 이 코드 는 어떻게 복구 합 니까?규칙 2,3 임 의 1 을 만족 시 키 면 된다.
    happen-before 원칙 은 JMM 에서 매우 중요 한 원칙 으로 데이터 에 경쟁 이 있 는 지,스 레 드 가 안전 한 지 를 판단 하 는 주요 근거 로 다 중 스 레 드 환경 에서 의 가시 성 을 확보 했다.
    다음 그림 은 happens-before 와 JMM 의 관계 도 입 니 다.

    이상 은 본문의 전체 내용 입 니 다.여러분 의 학습 에 도움 이 되 기 를 바 랍 니 다.여러분 도 저 희 를 많이 지지 해 주시 기 바 랍 니 다.

    좋은 웹페이지 즐겨찾기