자바 에서 volatile 키 워드 를 분석 합 니 다.

자바 다 중 스 레 드 프로 그래 밍 에서 volatile 을 자주 사용 합 니 다. 가끔 은 이 키워드 와 synchronized 또는 lock 이 헷 갈 릴 때 가 있 습 니 다. 구체 적 으로 다음 과 같이 해석 합 니 다.
다 중 스 레 드 환경 에서 구성원 변 수 를 볼 수 있 는 문제 가 존재 합 니 다. 자바 의 모든 스 레 드 는 하나의 스 레 드 스 택 의 메모리 공간 이 존재 합 니 다. 이 메모리 공간 은 이 스 레 드 가 실 행 될 때의 변수 정 보 를 저장 합 니 다. 스 레 드 가 특정한 변수 값 에 접근 할 때 먼저 이 변수의 주소 에 따라 대상 의 메모리 나 스 택 저장 (원생 데이터 형식) 의 구체 적 인 내용 을 찾 습 니 다.그 다음 에 이 안에 하나의 복사 본 을 이 스 레 드 의 스 레 드 스 택 에 저장 하고 이 변수 에 대한 모든 작업 은 스 레 드 가 종료 되 기 전에 스 택 메모리 의 변수 내용 과 관계 가 없 으 며 자신의 스 레 드 스 택 의 복사 본 을 조작 합 니 다.작업 이 끝 난 후에 작업 이 끝 난 결 과 를 메 인 메모리 에 다시 쓸 것 입 니 다.만약 에 두 개의 스 레 드 A 와 B 가 있다 면 동료 가 특정한 변수 x 를 조작 합 니 다.A. x 에 1 을 더 하면 B 가 얻 은 복사 본 은 x 가 1 을 더 한 결과 일 수도 있 고 x 일 수도 있 습 니 다.메모리 의 최신 데이터 변 수 를 얻 기 위해 서 는 volatile 키 워드 를 추가 해 야 합 니 다. 그러면 x 를 조작 할 때마다 오프라인 스 택 에 있 는 변수의 값 이 메모리 에 있 는 변수의 값 과 같 는 지 확인 합 니 다.다 르 면 다시 로드 할 게 요.
eg:
public class ThreadSee {
//t1     flag        ,      t1  
 public static void main(String[] args) throws InterruptedException {
        ThReadTest th=  new ThReadTest();
        Thread t1 = new Thread(th);
        t1.start();
        Thread.sleep(1000);
        th.changeFlag();
        Thread.sleep(2000);
        System.out.println(th.getFlag());
    }

}


class ThReadTest implements Runnable{

   //          load        ,                 
    private  volatile boolean  stopflag;
    @Override
    public void run() {
        int i=0;
        while(!stopflag){
            i++;
            System.out.println("=="+Thread.currentThread().getName());
        }
        System.out.println("Thread finish:"+i);
    }
    public void changeFlag(){
        this.stopflag=true;
        System.out.println(Thread.currentThread().getName()+"***********");
    }

    public boolean getFlag(){
        return stopflag;
    }
}

이 코드 는 volatile 을 제거 하면 계속 순환 적 으로 실 행 됩 니 다.
그러나 volatile 은 라인 의 안전 한 동기 화 를 보장 할 수 없다
eg:
4. 567913. 상기 코드 에 따라 실 행 된 결 과 는 20000 이 예상 되 지 않 았 습 니 다.
volatile 수식 변수 에 대해 jvm 가상 머 신 은 메 인 메모리 에서 스 레 드 작업 메모리 로 불 러 오 는 값 이 최신 임 을 보증 하기 때 문 입 니 다.
예 를 들 어 스 레 드 1, 스 레 드 2 가 스 레 드 스 택 과 메 인 메모리 read, load 작업 에서 메 인 메모리 의 count 값 이 모두 5 인 것 을 발견 하면 이 최신 값 을 불 러 옵 니 다.
스 레 드 1 더미 count 를 수정 하면 주 메모리 에 write 되 고 주 메모리 의 count 변 수 는 6 으로 변 합 니 다.
스 레 드 2 는 read, load 작업 이 진행 되 었 기 때문에 연산 을 한 후에 도 메 인 메모리 count 의 변 수 를 6 으로 업데이트 합 니 다.
두 스 레 드 를 volatile 키워드 로 수정 한 후에 도 동시 다발 적 인 상황 이 발생 할 수 있 습 니 다.
위 에서 말 한 바 와 같이:
volatile 은 현재 스 레 드 스 택 의 변수 값 과 메 인 메모리 의 데이터 값 이 같은 지 확인 하 는 동작 만 할 수 있 습 니 다. 이것 뿐 입 니 다.lock 또는 synchronized 어느 순간 에 하나의 스 레 드 만 이 방법 에 들 어가 서 스 레 드 의 안전성 을 확보 할 것 이다.
그래서 여러 스 레 드 에서 volatile 변 수 를 수정 하면 실제 적 인 논리 적 의미 가 없습니다.한 스 레 드 가 다른 스 레 드 가 수 정 된 변수 값 에 의존 하 는 것 을 수정 하면 이 때 는 역할 을 합 니 다.

좋은 웹페이지 즐겨찾기