JAVA 낙관 잠 금 소결
4181 단어 자바 기반
뭐 공부 해요?
, , ?
말 그대로 낙관 의 자 물 쇠 는 이상 화 된 상태 로 매우 낙관적이다.데 이 터 를 찾 으 러 갈 때마다 다른 스 레 드 가 이 데 이 터 를 수정 하지 않 을 것 이 라 고 생각 하기 때문에 잠 금 을 고려 하지 않 습 니 다.
낙관적 인 자 물 쇠 를 바탕 으로 하 는 사상 은 여러 가지 실현 방식 이 있 는데, 여기까지 이야기 하면 오늘 의 주인공 이 바로 CAS ("Compare and Swap) 라 고 말 할 수 밖 에 없다.
CAS 기술
CAS 는 낙관적 인 잠 금 의 전형 적 인 구현 방식 입 니 다. 여러 스 레 드 가 하나의 변 수 를 업데이트 하려 고 시도 할 때 하나의 스 레 드 만 업데이트 에 성공 할 수 있 고 다른 스 레 드 는 업데이트 에 실 패 했 음 을 알 립 니 다. 그러나 실패 한 스 레 드 는 걸 리 지 않 고 자전 하 며 다시 시도 합 니 다. 전체 CAS 구현 중 몇 가지 매개 변 수 는 설명 할 필요 가 있 습 니 다. V (메모리 의 새 값), A.(기대치), B (기록 할 값) 입 니 다. CAS 작업 과정 은 다음 과 같 습 니 다. 메모리 에 있 는 오래된 값 을 한 번 읽 어서 기대치 로 삼 은 다음, 데이터 B 에 들 어가 기 전에 메모리 에서 이 값 이 수정 되 었 는 지 다시 읽 으 려 고 합 니 다. 수정 되면 (A! = V)다음 동작 을 포기 하고 다시 시도 합 니 다. 수정 되 지 않 았 다 면 이 값 을 기록 합 니 다. 간단 한 경량급 구현 방식 으로 인해 JUC 에서 도 CAS 를 기반 으로 구현 하 는 도구 류 가 많 습 니 다. Atomic 관련 류, ReentrantLock 의 FairSync 류 등 입 니 다.
다음은 소스 코드 방식 을 통 해 CAS 가 AtomicInteger 류 에서 의 응용 을 구체 적 으로 살 펴 보 겠 습 니 다.
AtomicInteger
AtomicInteger 에 대해 우 리 는 getAndIncrement () 방법 을 통 해 CAS 의 작업 원리 와 CAS 의 일부 특성 을 엿 볼 수 있다.
전체 getAndIncrement 방법 호출 체인:
graph LR
AtomicInteger.getAndIncrement-->unsafe.getAndAddInt
unsafe.getAndAddInt -->this.compareAndSwapInt
compare AndSwapInt 는 전체 getAndIncrement 가 실현 하 는 관건 입 니 다. 원본 코드 를 통 해 compare AndSwapInt 는 native 수식 자 를 수식 하 는 로 컬 방법 임 을 알 수 있 습 니 다. 자 료 를 찾 은 후에 저 는 이 방법 에 대해 더 알 게 되 었 습 니 다. 즉, compare AndSwapInt 는 Unsafe 클래스 에서 Atomic: cmpxchg (이 방법 은 winodws x86 과 linux x86 에서 모두 실현 되 었 습 니 다) 를 호출 합 니 다.구체 적
1. os: is mp () 방법 을 통 해 다 중 처리 시스템 인지 여 부 를 판단 합 니 다. (단일 프로세서 시스템 이 라면 lock 명령 을 추가 하여 성능 비용 을 줄 일 필요 가 없습니다)
2. Lock If MP (mp) 는 mp 의 값 에 따라 cmpxchg 에 lock 접 두 사 를 추가 할 지 여 부 를 결정 합 니 다. (주) 이 곳 의 cmpxchg 는 어 셈 블 리 명령 으로 비교 와 교환 역할 을 합 니 다)
또한 Intel 매 뉴 얼 은 lock 명령 에 대해 다음 과 같이 설명 합 니 다.
위의 설명 을 통 해 알 수 있 듯 이 코드 차원 에서 CAS 는 잠 금 을 추가 하지 않 았 지만 최종 적 으로 하나의 스 레 드 만 목표 변 수 를 조작 할 수 있 습 니 다. 그 밖 에 CAS 는 하나의 공유 변 수 를 조작 하 는 원자 조작 을 보장 하고 volatile 의 읽 기와 쓰기 의 미 를 가지 고 있 습 니 다.
CAS 에 무슨 문제 가 생 길 수 있 습 니까?
위 에서 우 리 는 CAS 의 원리 와 응용 을 알 게 되 었 습 니 다. 그러면 우 리 는 한 가지 문 제 를 생각해 야 합 니 다. 우리 가 CAS 를 사용 하여 병행 작업 을 할 때 어떤 문제 가 발생 할 수 있 습 니까? 여기 서 우 리 는 주로 세 가지 문 제 를 정리 할 수 있 습 니 다.
ABA 문 제 는 CAS 를 사용 할 때 가장 자주 발생 하 는 문제 입 니 다. 전체 과정 은 다음 과 같 습 니 다.
sequenceDiagram
A( 2 , 3 )->> 1:
A( 2 , 3 )->> 2:
2->>A( 2 , 3 ):
A( 2 , 3 )->> 3:
3->>A( 2 , 3 ):
1->>A( 2 , 3 ):
위의 그림 을 통 해 알 수 있 듯 이 스 레 드 1 은 CAS 가 성공 적 으로 작 성 했 지만 이 A 값 이 전체 과정 에서 발생 하 는 문 제 를 느끼 지 못 했다. 그 값 이 변 하지 않 았 을 수도 있 지만 그 의 미 는 이미 변 했다. 사실 이런 장면 도 매우 흔 하 다. 예 를 들 어 우리 의 업무 에서 우 리 는 기록 데 이 터 를 수정 하기 전에 데이터 의 여 부 를 검증 해 야 한다.변화 가 있 었 다 면, 변화 가 없 었 다 면 기록 하고, 변화 가 있 었 다 면 포기 했다. 이 는 어느 정도 병발 도 를 높 일 수 있다.
ABA ?
ABA 문제 에 대한 일반적인 해결 방향 은 정 보 를 기록 할 수 있 는 유일한 태그 값 을 만 드 는 것 입 니 다. 예 를 들 어 이 필드 를 조작 할 때마다 이 값 에 1 을 추가 할 수 있 습 니 다. 데 이 터 를 쓰기 전에 이 값 이 이 방법 에 들 어 갈 때 읽 은 값 과 같 는 지 비교 할 수 있 습 니 다. 처음 외 에 버 전 번호 와 시간 스탬프 를 기록 할 수 있 습 니 다.
자전 에 따 른 CPU 자원 낭비 문제
위의 분석 에 따 르 면 CAS 를 기록 하 는 과정 에서 기록 에 실패 하면 스 레 드 가 걸 리 지 않 고 자전 하 며 다시 시도 하 는 것 으로 나 타 났 습 니 다. 어떤 극단 적 인 장면 에 서 는 순환 이 죽 거나 CPU 자원 의 헛 된 낭 비 를 초래 할 수 있 습 니 다. 평소 인 코딩 과정 에서 jdk 1.6 이후 synchronized 를 잠 금 업그레이드 하 는 방향 도 고려 할 수 있 습 니 다.일정 횟수 로 자전 할 수 없 거나 자원 이 있 을 때, 우 리 는 이 임 무 를 포기 하고 null 값 으로 돌아 가 거나 중량급 자물쇠 로 주동 적 으로 업그레이드 하 는 것 을 고려 할 수 있 습 니 다.
이상 은 바로 제 가 경량급 자 물 쇠 를 배 울 때 정리 와 인식 입 니 다. 필요 한 사람 에 게 도움 이 되 기 를 바 랍 니 다. 또한 여러분 들 이 잘못 을 지적 하고 댓 글 을 남 겨 진일보 한 토론 을 할 수 있 기 를 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
범용 용법 예시앞으로 51CTO 에 정착 해 기술 개발 에 전념 할 테 니 잘 부탁드립니다.다음 코드 는 자신 이 (저자: 이 흥 화) 를 공부 할 때 두 드 린 코드 로 주석 이 완비 되 어 있다. 범용 클래스 Point. ja...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.