자바 초보 입문 면접 문제,자유 로 운 길 로 가 는 자물쇠+Volatile

1.volatile 이 가시 성 을 어떻게 보장 하 는 지 아 세 요?
우 리 는 먼저 코드 한 세트 를 보 았 다.

public class VolatileVisibleDemo {
    public static boolean initFlag = false;
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("  initFlag  !!!");
                //   initFlag     ,   true  ,      
                while(!initFlag) {
                }
                System.out.println("        ,  !");
            }
        }).start();
        //                 
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //    Lambda   ,       
        new Thread(() -> {
            System.out.println("      ,  initFlag  ");
            initFlag = true;
            System.out.println("      !");
        }).start();
    }
}
실행 결과:

우 리 는 사실 데 이 터 를 준비 한 후에 우리 의 initFlag 변 수 는 이미 바 뀌 었 지만 왜 순환 수출 을 끝내 지 않 았 는 지 알 수 있 습 니 다**오늘 의 세 계 는 문 을 닫 았 습 니 다.안녕 히 주 무 세 요!**이 한 마디 는?
사이 의 JMM 모델 에서 우 리 는 서로 다른 스 레 드 간 에 상대방 의 작업 메모리 에 직접 접근 할 수 없 는 변수 임 을 알 수 있 습 니 다.스 레 드 간 변수의 값 전달 은 메 인 메모리 에서 이 루어 져 야 합 니 다.또한 스 레 드 는 수 치 를 수정 한 후에 바로 메 인 메모리 에 동기 화 되 는 것 이 아니 라 다른 스 레 드 도 데이터 가 바 뀌 는 것 을 감지 할 수 없습니다.그래서 가시 적 인 문제 가 생 길 수 있 습 니 다.
그럼 volatile 키워드 수식 변 수 를 추가 해 볼 까요?

 public static volatile boolean initFlag = false;
우 리 는 발견 할 수 있다.

우리 의 변수 가 volatile 키 워드 를 수식 한 후에 출력 할 수 있 습 니 다**오늘 의 세 계 는 문 을 닫 았 습 니 다.안녕 히 주 무 세 요!**이 한 마디 야.
우리 도 해 를 봅 시다.

그 중 에 연 결 된 몇 개의 단 어 를 먼저 설명 하 세 요.
  • read(읽 기):주 메모리 에서 데 이 터 를 읽 습 니 다
  • load(불 러 오기):주 메모리 에서 읽 은 데 이 터 를 로 컬(작업)메모리 에
  • 에 기록 합 니 다.
  • user(사용):로 컬 메모리 에서 데 이 터 를 읽 어 스 레 드 에 사용 하여
  • 을 계산 합 니 다.
  • assign(할당):스 레 드 는 계 산 된 값 을 작업 메모리 에 다시 할당 합 니 다
  • store(저장):로 컬 메모리 의 데 이 터 를 주 메모리 에 저장 합 니 다
  • write(쓰기):stroe 에서 온 변수 값 을 주 메모리 의 변수 에 할당 하고 다시 할당 합 니 다.
  • 대충 절 차 를 말씀 드 리 겠 습 니 다.
    온라인 프로 세 스 B 에서 initFlag 변 수 를 읽 은 후 변 수 를 true 로 다시 할당 합 니 다.이 때 는 volatile 수식 이 추가 되 어 있 기 때문에 바로 메 인 메모리 에 값 을 기록 하여 변 수 를 수정 합 니 다.이 때 cpu 버스 탐지 기 가 메 인 메모리 의 변 수 를 감청 하여 로 컬 메모리 의 initFlag 변 수 를 실효 로 설정 합 니 다.메 인 메모리 의 새 값 을 다시 읽 으 면 변수의 가시 적 인 문 제 를 해결 할 수 있 습 니 다.이것 은 그것 의 첫 번 째 가시 성 을 보장 하 는 관건 이다.
    앞서 우리 도 그 가 명령 을 내 려 정렬 을 다시 한다 면 최신 값 을 읽 을 수 없 지 않 을 까 하 는 언급 이 있 었 다.답 은 안 나 오 는데.
    volatile 에 의 해 수식 되면 정렬 을 금지 하기 때문이다.그것 은 주로 어떤 명령 에 의 해 정렬 됩 니까?그것 은 메모리 장벽 을 통 해 이 루어 진 것 이다.무엇이 메모리 장벽 입 니까?하드웨어 차원 에서 메모리 장벽 은 두 가지 로 나 뉜 다.읽 기 장벽(Load Barrier)과 쓰기 장벽(Store Barrier)이다.메모리 장벽 은 두 가지 작용 이 있다.
  • 장벽 양쪽 의 명령 재 정렬 을 막 기;
  • 은 버퍼/캐 시 에 있 는 더러 운 데이터 등 을 메 인 메모리 에 강제로 쓰 거나 캐 시 에 있 는 데 이 터 를 무효 화 합 니 다.
  • 컴 파일 러 는 바이트 코드 를 생 성 할 때 명령 시퀀스 에 메모리 장벽 을 삽입 하여 명령 의 정렬 을 금지한다.이렇게 하면 모든 프로그램 에서 정확 한 volatile 메모리 의 미 를 얻 을 수 있다.이 정책 은:
  • 모든 volatile 쓰기 전에 StoreStore 장벽 을 삽입 합 니 다.
  • 은 모든 volatile 에서 동작 을 쓴 후에 StoreLoad 장벽 을 삽입 합 니 다.
  • 은 모든 volatile 읽 기 동작 후 Load Load 장벽 을 삽입 합 니 다.
  • 은 모든 volatile 에서 읽 기 동작 을 한 후에 Loadstore 장벽 을 삽입 합 니 다.
  • 설명도 보기:

    소결:
    volatile 역할:
  • volatile 은 메모리 의 가시 성 을 확보 하고 정렬 을 금지 할 수 있 습 니 다.
  • volatile 은 원자 성 을 보장 하지 않 고 자 물 쇠 는 전체 임계 구역 코드 의 집행 이 원자 성 을 가 진 다 는 것 을 보증 할 수 있다.그래서 자 물 쇠 는 전체 임계 구역 코드 의 집행 이 원자 성 을 가지 도록 보장 할 수 있다.그래서 기능 적 으로 자 물 쇠 는 volatile 보다 강하 다.성능 에 있어 서 volatile 이 더욱 우세 하 다.
  • 2.비관 자물쇠 와 낙관 자 물 쇠 는 당신 의 이 해 를 말 해 줄 수 있 습 니까?
    사실 이름 을 들 으 면 우 리 는 개념 이 있어 야 한다.
    비관 은 우리 생활 속 의 사람 에 게 대응 하고 비관 적 인 사람 은 일반적으로 사물 을 대 할 때 상대 적 으로 소극 적 이 고 부정적인 에 너 지 를 가지 고 가능 한 한 나 쁜 생각 을 한다.이것 도 마 이 걸 에 대응 하 는 것 이다.그녀 는 사실 비관 적 이 라 고 할 수 없 는 사람 이다.사물 을 보 는 것 이 더욱 깊이 있 고 나 쁜 한편 으로 생각 할 수 있다 고 말 할 수 밖 에 없다.
    이것 은 사실 저 와 상호 보완 적 입 니 다.낙 천적 인 편 이 라 고 할 수 있 습 니 다.우리 생활 속 의 사람들 에 게 낙관적 으로 대응 하고 있 습 니 다.낙관적 인 사람들 은 일반적으로 사물 을 대 할 때 상대 적 으로 적 극 적 이 고 긍정 적 이 며 가능 한 한 좋 은 쪽으로 생각 할 것 입 니 다.나 는 사실 생활 의 모든 면 에서 더 즐 거 운 견 해 를 가 질 수 있 지만,때때로 가 져 오 는 나 쁜 점도 예측 하기 어렵다.
    그래서 이 두 가 지 는 누가 좋 고 누가 나 쁜 지 말 할 수 없고 장면 에 대응 하여 대응 하 는 방법 을 선택 할 수 밖 에 없다.
    비관 자물쇠:
    MyGilr 라 는 사람 은 항상 최 악의 상황 을 가정 합 니 다.예 를 들 어 그녀 는 데 이 터 를 가 지 러 가 는 동시에 다른 사람 도 데 이 터 를 수정 해서 그녀 와 맞 설 것 이 라 고 생각 하기 때문에 데 이 터 를 가 지 러 갈 때마다 자 물 쇠 를 잠 그 고 한 계 를 막는다.그러면 다른 사람 이 이 데 이 터 를 가 지 려 면 그녀 가 나 가서 자 물 쇠 를 풀 때 까지 기다 릴 수 밖 에 없다.
    자바 에 서 는 synchronizedReentrantLock 등 독점 자물쇠 가 비관 적 자물쇠 사상의 실현 이다.데이터 베이스 에 이런 자물쇠 체 제 를 많이 사용 했다.예 를 들 어 줄 자물쇠,시계 자물쇠 등,읽 기 자물쇠,쓰기 자물쇠 등 은 모두 조작 하기 전에 먼저 자 물 쇠 를 잠 그 는 것 이다.
    낙관적 자물쇠:
    나 는 항상 가장 좋 은 상황 을 가정 한다.예 를 들 어 저 는 데 이 터 를 가 지 러 가 는 동시에 다른 사람 이 데 이 터 를 수정 하지 않 을 것 이 라 고 생각 하기 때문에 데 이 터 를 가 져 갈 때마다 잠 그 지 않 습 니 다.하지만 사람 은 마음의 준 비 를 해 야 하지 않 겠 습 니까?그래서 업데이트 할 때 이 기간 에 다른 사람 이 이 데 이 터 를 업데이트 한 적 이 있 는 지 판단 합 니 다.
    흔히 볼 수 있 는 것 은 CAS 알고리즘+버 전 번호 가 있 습 니 다.낙관적 인 잠 금 은 다 독 의 응용 유형 에 적합 하여 스루풋 을 높 일 수 있다.
    자바 에서 원자 류 와 같은 것 은 낙관적 인 자 물 쇠 를 사용 한 실현 방식 인 CAS 로 이 루어 진 것 이다.데이터베이스 에서 제공 하 는 write 와 유사 합 니 다.condition 메커니즘 은 사실 모두 낙관적 인 자 물 쇠 를 제공 합 니 다.
    이들 이 대응 하 는 장면 의 차이 점:
    낙관적 인 자 물 쇠 는 주로 읽 고 쓰기 가 적은 환경 에 사용 되 고 자주 자 물 쇠 를 추가 하여 성능 에 영향 을 주지 않도록 시스템 의 전체 스루풋 을 증가 시 켰 다.비관 적 인 자 물 쇠 는 많이 쓰 고 적 게 읽 는 환경 에 많이 사용 되 며 잦 은 실패 와 재 시도 가 성능 에 영향 을 주지 않도록 한다.
    3.다른 자물쇠 도 알 아 요?
    잠 금 을 다시 들 어 갈 수 있 고 다시 들 어 갈 수 없 는 잠 금:
    다시 자 물 쇠 를 재 귀 자물쇠 라 고도 부 르 는 것 은 말 그대로 다.다시 들 어 가 는 자 물 쇠 를 지원 하 는 것 입 니 다.즉,이 자 물 쇠 는 자원 에 대한 중복 자 물 쇠 를 지원 합 니 다.같은 스 레 드 가 외부 에서 자 물 쇠 를 가 져 올 때 내부 로 들 어 가 는 방법 으로 자동 으로 자 물 쇠 를 가 져 오 는 것 을 말한다.이전에 얻 었 다 고 해서 아직 풀 리 지 않 았 다 고 해서 막 히 지 는 않 을 것 이다.
    자바 에 서 는 ReentrantLocksynchronized 이 모두 잠 금 을 다시 넣 을 수 있 고 잠 금 을 다시 넣 을 수 있 는 또 다른 장점 은 잠 금 을 어느 정도 피 할 수 있다 는 것 이다.
    
    public static void main(String[] args) {
        doOne();
    }
    public static synchronized  void doOne(){
        System.out.println("       ");
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //        
        doTwo();
    }
    public static synchronized  void doTwo(){
        System.out.println("       ");
    }
    
    간단 한 테스트 결과:
    첫 번 째 미 션 수행
    두 번 째 임 무 를 수행 하 다
    클래스 의 두 가지 방법 은 모두 내 장 된 잠 금 synchronized 에 의 해 수 정 된 것 임 을 검증 할 수 있 습 니 다.doOne 방법 에서 doTwo 방법 을 호출 할 때 잠 금 을 다시 넣 을 수 있 기 때문에 같은 스 레 드 에서 현재 대상 의 자 물 쇠 를 직접 얻 을 수 있 기 때문에 synchronized 은 잠 금 을 다시 넣 을 수 있 습 니 다.
    만약 에 우리 가 AQS 를 계승 하여 동기 화 기 를 실현 할 때 자 물 쇠 를 차지 하 는 스 레 드 가 다시 자 물 쇠 를 가 져 오 는 장면 을 고려 하지 않 으 면 스 레 드 가 막 힐 수 있 습 니 다.이것 은 바로 다시 자 물 쇠 를 넣 을 수 없 는 것 입 니 다.
    공평 자물쇠 와 불공평 자물쇠:
    이곳 의 공평 함 은 생활 에 따라 말 할 수 있 습 니 다.만약 당신 이 여자 친구 와 싸 우 면 당신 이 옳다 고 생각 합 니 다.마지막 결 과 는 당신 이 여자 친 구 를 달 래 야 하고 사과 해 야 합 니 다.당신 은 믿 습 니까?그래서 이게 공평 한 건 가요?
    자물쇠 에 있어 서 먼저 자물쇠 가 요청 한 스 레 드 를 가 져 오 면 먼저 만족 하고 자물쇠 가 요청 한 스 레 드 를 가 져 온 후에 만족 합 니 다.그러면 이 자 물 쇠 는 공평 합 니 다.반대로 그것 은 불공평 한 것 이다.
    공평 한 자물쇠:
    여러 스 레 드 는 자 물 쇠 를 신청 하 는 순서에 따라 자 물 쇠 를 가 져 옵 니 다.스 레 드 는 대기 열 에 직접 들 어가 줄 을 서 야 대기 열 에 있 는 첫 번 째 스 레 드 가 자 물 쇠 를 얻 을 수 있 습 니 다.공정 자물쇠 의 장점 은 자 물 쇠 를 기다 리 는 스 레 드 가 굶 어 죽지 않 는 다 는 것 이다.
    단점 은 전체 삼투 효율 이 상대 적 으로 불공 정 잠 금 보다 낮 고 대기 열 에서 첫 번 째 스 레 드 를 제외 한 모든 스 레 드 가 막 히 며 CPU 가 스 레 드 를 깨 우 는 비용 이 불공 정 잠 금 보다 크다 는 것 이다.
    불공평 한 잠 금:
    여러 스 레 드 에 자 물 쇠 를 추가 할 때 자 물 쇠 를 가 져 오 려 고 시도 합 니 다.가 져 오지 못 해 대기 행렬 의 끝 에 대기 할 수 있 습 니 다.그러나 이때 잠 금 을 사용 할 수 있다 면 이 스 레 드 는 차단 하지 않 고 잠 금 을 직접 가 져 올 수 있 기 때문에 불공 정 잠 금 이 발생 한 후에 잠 금 을 신청 하 는 스 레 드 가 먼저 잠 금 을 가 져 오 는 장면 이 있 을 수 있 습 니 다.
    불공 정 잠 금 의 장점 은 스 레 드 를 불 러 일 으 키 는 비용 을 줄 일 수 있 고 전체적인 삼투 효율 이 높다 는 것 이다.스 레 드 가 막 히 지 않 고 직접 잠 금 을 얻 을 수 있 기 때문에 CPU 는 모든 스 레 드 를 깨 울 필요 가 없다.대기 열 에 있 는 스 레 드 가 굶 어 죽 거나 오래 기 다 려 야 자 물 쇠 를 얻 는 것 이 단점 이다.
    자바 에 서 는 ReentrantLock 의 경우 구조 함 수 를 통 해 이 자물쇠 가 공평 한 자물쇠 인지 아 닌 지 를 지정 할 수 있 으 며,기본적으로 불공평 한 자물쇠 입 니 다.
    독점 자물쇠 와 공유 자물쇠:
    독차지 와 공유 에 대해 서 는 명지 의 를 볼 수 있 을 것 이다.마 이 걸 이 좋아 하 는 것 은 건 드 려 도 건 드 리 지 못 하고 싫어 하거나 괜 찮 은 것 은 그녀 와 공유 할 수 있다.
    독점 자물쇠:
    배타 자물쇠 라 고도 하 는데 이 자 물 쇠 는 한 번 에 한 라인 만 가지 고 있 는 것 을 말한다.스 레 드 B 가 변수 A 에 자 물 쇠 를 추가 하면 다른 스 레 드 는 A 에 어떤 종류의 자 물 쇠 를 추가 할 수 없습니다.자 물 쇠 를 독점 하 는 스 레 드 를 얻 으 면 데 이 터 를 읽 을 수 있 고 데 이 터 를 수정 할 수 있 습 니 다.
    자바 에서 synchronized 은 일종 의 독점 자물쇠 이다.
    공유 잠 금:
    이 자 물 쇠 는 여러 스 레 드 에 의 해 소유 할 수 있 음 을 의미 합 니 다.스 레 드 B 가 변수 A 에 공유 자 물 쇠 를 추가 하면 다른 스 레 드 는 A 에 공유 자 물 쇠 를 추가 할 수 있 을 뿐 자 물 쇠 를 추가 할 수 없습니다.공유 잠 금 을 얻 은 스 레 드 는 데이터 만 읽 을 수 있 고 데 이 터 를 수정 할 수 없습니다.
    총결산
    이 글 은 여기까지 입 니 다.만약 이 글 이 당신 에 게 도 도움 이 된다 면,당신 이 우리 의 더 많은 내용 에 관심 을 가 져 주시 기 바 랍 니 다!

    좋은 웹페이지 즐겨찾기