-2 바이어스 잠금 부분 잠금 [지식 시스템의 기본 자바 건설에 브러시 표면에서 질문] -synchronized

피라미드 구조를 구축함으로써, 다른 각도에서, 동기화 된 키워드에 대한 진보적 인 접근 방식을 도입했다

빠른 이동 : https://www.cnblogs.com/xyang/p/11631866.html

자세한 진행 기본이되는 구현의 다양한 "구성 요소"에서이 문서는 작동 해체.

이 문서는 다음 섹션 4 컨텐츠로 구분됩니다

  섹션 I : 소개 MarkWord과 지식이 동기화 된 키워드의 기본 원리를 이해하는 열쇠이다 LockRecord 두 개의 데이터 구조.

  섹션 II는 : 분석 잠금 해제시기와 과정을 잠금 바이어스

A. 두 개의 데이터 구조를 이해하는 것이 첫 번째, 당신은 지식 포인트를 이해한다

1.MarkWord는 : 객체를 잠급니다 잠금 과정에서 해당 작업을 만들려면

 오브젝트 헤더 인스턴스 데이터, 정렬 심 : 핫스팟 가상 머신에서, 메모리 레이아웃에 저장된 Java 오브젝트는 세 부분으로 나뉘어진다.

이 문서에서는 객체 머리에 초점을 맞추고 있습니다.

헤더 객체는 두 개 또는 세 개의 부분으로 분할되고, 포함 :

  1. MarkWord (이하 ​​MW 이후 상세히이라 함)
  2. 유형 포인터가이 데이터 클래스의 메타 데이터 개체에 대한 포인터가 속한 (클라스)의
  3. 이 마지막 부분은 객체의 존재 만 자바 배열 배열의 길이를 기록에서만이 아니라 특별하다. 왜이 기록은 무엇입니까? 우리는 보통의 자바 객체에, 우리는 객체의 클래스의 메타 데이터 오브젝트의 계산 된 크기를 읽을 수 있다는 것을 알고있다. 배열이 완료, 그래서이 지역을 기록하는 데 도움이 될 수 없습니다.

이 문서에서는 MW 영역에 초점을 맞추고

MW는 고정 된 크기의 메모리 영역은 가상 머신 (64)에 대응하는 32 비트 가상 머신에서 32 비트 64 비트이다. 이 논문에서는, 예를 들어 32 비트 가상 머신을 분석한다.

우리가 사용하는 소위 헤더 정보는 일반적으로 HTTP의 헤더 요청에서 예를 들어, 다양한 헤더 정보, 정보의 일부는 쉽게 변형되지 않는 설명, 직관적으로 이해합니다. 동일한 개체의 헤더, 예를 들어 해시의 사실이다. JVM에서 가상 머신의 메모리 공간 오버 헤드를 해결하기 위해, MW 객체 헤더는 고정 된 크기를 갖는다. 그래서, 더 많은 정보를 포함하여 저장 이에 국한되지 가지고 : 잠금 플래그, GC 정보, 잠금 정보, 전체 크기는 지금까지 32 비트 이상, 그것을 어떻게 할까?

스토리지 요구 정보의 요구에 따라, 상이한 시간에 메모리 영역을 공유.

다음 표를 참조하십시오 :

잠금 유형

25bit

4 비트

1 비트

2 비트

 

23bit

2 비트

바이어스 잠금 여부

잠금 플래그

없음 잠금 없다

객체의 해시 코드

세대 시대

0

01

바이어스 잠금

스레드 ID

시대

세대 시대

1

01

경량 잠금

스택 포인터 레코드 잠금 포인팅

00

헤비급 잠금

포인팅 뮤텍스

(10)

GC 마크

(11)

 

설명 : 두 플래그는 다음 나머지는 어떻게 공유 할, 네 가지 상태까지 식별 할 수? 바이어스 잠금 및 비 잠금은 두 사람 사이에 01 주, 구별을 공유

2.LockRecord :

제 2 부분 (OBJ), 점 로크 대상, 현재 스레드의 스택 LR 요청 개의 주요 부분을 포함하고, (LockRecord 이하 동일 함), 제 단차 부는 MW의 복사본을 저장하는데 사용될 수있다.

 둘 사이의 관계는 다음 도표에 의해 표현된다 :

 

 

II. 어떻게 바이어스 잠금을 작업

객체가 생성되면, MW는 어떠한 잠금 상태 혹은 초기 상태 편향된 로킹 (ThreadId, 초기 값 0 에포크 값) 중 어느 하나를 초기 상태가 없습니다. -XX : -UseBiasedLocking을 프로그래머의 세계는 그것은 당신이 밖으로하지 않으려면 JDK1.6 후, 기본적으로 활성화되어, 가상 머신의 선택 구성 매개 변수를 기반으로, 결국 하나를 선택합니다, 모호함이 없습니다.

언제 비활성화해야합니까? 프로그램이 대부분의 경우에서 확인 될 수 있다면, 여러 스레드가 경쟁합니다, 당신은 바이어스 잠금을 해제 할 수 있습니다. 모든 바이어스 잠금을 통해 갈 필요가 없습니다 -> 경량 잠금 -> 잠금 헤비급 업그레이드 프로세스를 완료합니다.

도 1. 먼저, 해제, 기본 흐름 해지 편향된 로킹 자물쇠 직관적 설명 넣어

 

 

 

 

2. 잠금 절차

 단계 :

  1. LR 기록 할당 : 현재의 thread의 스택에서 락 객체의 OBJ를 가리키는하는 LR을 적용

단계 2 :도 스레드 T1에 도시이, 동기 코드를 실행하도록하는 바이어스 잠금을 추가하려고, 제 1 자물쇠는 바이어스 DO [사용할] 결정은 :

  1. 오브젝트 헤더 다음 세 비트 영역의 비트 값은 MW가 101 개체를 잠근다. 특히 주목할 : 001 잠금이없는 상태 인 경우 바이어스 잠금 대신 사용할 수 없습니다에, 그것은 잠금 플러스 경량 프로세스를 이동합니다.
  2. 值 ThreadId :
    1. ThreadId = 0, 어떤 바이어스 로킹 스레드에는 대표 객체 잠금 조작이 수행 될를 보유하지 않는 경우, 처리는 로크를 입력;
    2. ! 재진입 직접 고정하는 경우, 잠금 반복하지 않는다 : ThreadId = 0 인 경우, 현재 스레드 ID 두 케이스의 값이 있는지 여부를 판단한다. 그렇지 않다면, 그 다른 스레드 (도 T2)는 동기 로크는 "세번째 단계"프로세스 로크 경합을 입력 받고있다.
  3. 시대 값 : 객체가 클래스에 속한다는 cEpoch으로, 판단의 값이 두 가지로 이어질 수에 우리가 언급 여기하는 시대 값을 유지한다 :
    1. 에포크는 <cEpoch 및 ThreadId! = 0, 무거운 바이어스 전류 로크 대상의 과도한 수량의 발생을 나타내는 것은 "방출"된 경우. 이 시점에서 "무거운 바이어스"(박리가 진정한 의미를 방출하지만, 의미의 층을 의미되지 말한다 현재 스레드 동기화 블록을 실행하고 있으며, 중쇄 특정 동작 바이어스뿐만 아니라이를 감지 이 때 새 스레드가 바이어스 잠금을 믿을 수 있도록 더 이상 신기원의 현재 값을 유지) ThreadId을 수정 CAS에 직접 고정 할 수 없습니다.
    2. 디스플레이 기술 바이어스 ThreadId 프로세스 확실히 초기 상태 변경되므로 ThreadId == 0이 로크가 폐기되지 않으면, 에폭 값 0은 직접이 때 잠금 동작의 초기 상태에 확실하다.

    아래와 같이 MW 함량은 록킹 상태 :

    

잠금 유형

25bit

 

4 비트

1 비트

2 비트

 

23bit

2 비트

 

바이어스 잠금 여부

잠금 플래그

바이어스 잠금

ThreadId == 0

에포크 == N

세대 시대

1

01

 

     그것은 "두 번째 단계"프로세스 잠금으로, 세 개 이상의 점에 의해 결정되는

단계 2 : CAS 원자 조작함으로써, T1이 기록된다 MW를 ThreadId. 두 가지 상황의 결과 :

  1. 성공적으로 기록, 편향된 로킹 동기 부호 동기화 로직 블록이 실행에 얻어진다.
  2. 판사와 CAS 작업 사이의 첫 번째 단계는, 잠금을 얻고있다 다른 스레드가 있음을 나타냅니다 실패를 작성합니다. 잠금 경쟁 논리를 이동합니다.

2. 잠금 해제 과정

현재 스레드 동기화 코드 블록의 구현을 완료 한 후, 잠금 해제 동작이 최근 할당 OBJ 만 스택 LR가 null 비교적 간단 해제된다. 그것은 주목해야한다, threadId의 MW되지는 변경합니다.

 

 

3. 잠금 경쟁 프로세스 흐름

  잠금을 보유 T2 스레드가 처음으로 발견 직접적인 경쟁 해지 잠금 또는 잠금 업그레이드, 그러나 치료 후 안전한 지점의 구현되지 않습니다.

  1. 현재 스레드 동기화 블록의 코드를 실행하는 경우,이 시점에서, 스레드가 로크의 비 잠금 상태로 오브젝트를 복원 인출 잠근다 생존하지 않은 후, 로직은 잠금 이관 들어간다.
  2. 현재 스레드 동기화 블록 실행이 완료되지 않았거나 스레드가 아직 살아 업그레이드 프로세스를 잠글 갈 경우, 업그레이드가 경량 잠금이며, T2 후 업그레이드, 경량 잠금을 동기화 코드를 수행하기 위해 계속합니다.

 

 

 

  PS : 어떻게 동기화 코드가 여전히 실행 여부를 확인하려면? 모두가 null의 경우 순회 스택 RL은 자물쇠를 대신하여 발표하고있다.

4. 일괄 무게와 부피 바이어스 해지

시나리오가있다 : 우리는 많은 경쟁을 예측하는 경우, 실행 동기 블록의 단일 스레드, 바이어스 잠금을 열어 대부분의 경우. 그러나 실제 사용 환경에서 그것을 할 방법이 시간, 많은 경쟁이있다? 다시 구성 매개 변수를 중지? 아마 없을 최고의 솔루션입니다. 우리가 동기화 잠금을 설계 할 경우이 확실히 약간의 포괄 전략을해야 할 것입니다. 특정 이벤트 내 치료 전략을 변경 한 후, N 번 발생하면 예를 들어,이 방법을합니까?

예, 바로 더 나은, 동일의 기본 개념은 일시적으로 다음에 발표 서스펜스를 떠나.

 

 

추천

출처www.cnblogs.com/xyang/p/11698549.html