java 자물쇠 지식 포인트 소기

4951 단어
java 자물쇠 지식 포인트: 1.라인 안전이란 무엇입니까: 표준 정의: 여러 개의 라인이 한 대상에 접근하는데 이러한 라인의 스케줄링과 교체 집행을 고려하지 않아도 되고 추가적인 동기화도 필요하지 않으며 호출 방법에서 어떠한 조율도 하지 않아도 이 대상을 호출하는 행위가 정확한 결과를 얻을 수 있다면 라인 안전이라고 합니다.위에서 정의한 협의적인 라인 안전은 실제적으로 라인 안전은 다섯 가지 강도로 나뉘는데 강에서 약으로 이를'불가변','절대 라인 안전','상대 라인 안전','라인 호환'과'라인 대립'으로 한다.1. 불가변: 불가변의 대상은 반드시 라인이 안전해야 한다. 대상의 방법이 실현되었든 방법의 호출자든 그 어떠한 안전 보장 조치도 취할 필요가 없다.2. 절대 라인 안전:'운행 환경이 어떻든지 간에 호출자는 어떠한 추가적인 동기화 조치도 하지 않는다'는 것은 보통 큰 대가를 치러야 한다.Java API에는 절대 스레드 보안이 아닌 스레드 보안 클래스가 표시됩니다.3. 상대적인 라인 안전: 우리가 흔히 말하는 라인 안전이다. 이 대상에 대한 단독 조작은 라인 안전이고 우리가 호출할 때 별도의 보장 조치를 취할 필요가 없다.그러나 일부 특정 순서의 연속 호출에 대해서는 호출단에서 추가 동기화 수단을 사용하여 호출의 정확성을 확보해야 할 수도 있다.4. 스레드 호환: 스레드 호환이란 대상 자체가 스레드가 안전한 것은 아니지만 호출단에서 동기화 수단을 정확하게 사용함으로써 대상이 병발 환경에서 안전하게 사용할 수 있도록 하는 것을 말한다.5. 라인 대립: 호출자가 동기화 조치를 취하든 안 하든 병발 환경에서 사용할 수 없는 코드를 말한다.
둘.자물쇠의 유형: 거시적으로 보면 자물쇠는 비관적 자물쇠(막힘동기)와 낙관적 자물쇠(비막힘동기) 낙관적 자물쇠(비막힘동기)로 나뉜다. 그리고 낙관적인 사상으로 먼저 조작을 하고 다른 라인이 공유 데이터를 다투지 않으면 조작이 성공한다. 만약에 공유 수량이 쟁용되고 충돌이 생기면 다른 보상 조치를 취한다.낙관적 자물쇠는 조작과 충돌 검측이 필요한 두 부분은 원자성을 가지고 하드웨어로만 완성할 수 있다. 하드웨어는 의미적으로 여러 개의 조작 절차가 필요한 행위를 하나의 지령만으로 완성할 수 있도록 보장한다. 이것은 다음과 같다.테스트 및 설정 2.획득 및 증가 3.바꾸다비교 및 교환(compareAndSwap CAS)5.링크/조건을 불러오는 자바의 낙관적인 자물쇠는 주로 CAS에 의해 완성된다. 카스는 세 가지 조작수를 필요로 하는데 그것이 바로 v조작 변수의 메모리 주소, A옛 예상값, B새 값이다.V에 저장된 값이 예상치 A일 경우 새 값이 업데이트됩니다. 위의 비교와 교환 작업은 원자입니다.java의 CAS 조작은sun을 통과합니다.misc.Unsafe 클래스가 구현된,java.util.concurrent 패키지의 원자류는 모두 CAS의 기초 위에 세워진 것이다.AtomicInteger의 getandIncrement() 작업과 같습니다.
public final int getAndIncrement() {
        return unsafe.getAndAddInt(this, valueOffset, 1);
}

unsafe의 getandAddInt 함수는 섹션 카스 작업이 성공했는지 확인하는 것입니다. 성공하지 않으면 계속 카스입니다.
    public final int getAndAddInt(Object var1, long var2, int var4) {
        int var5;
        do {
            var5 = this.getIntVolatile(var1, var2);
        } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

        return var5;
    }

compareAndSwapInt는 네 개의 매개 변수를 포함하고 var1은 대상의 인용을 가리키며 var2 조작 변수는 이 대상의 주소 편이량, var5 기대치, var5+var4 목표값을 가리킨다
 ( ): , , , ,java synchronized 。

셋.synchronize 밑바닥 실현 원리java1.5 이전에는synchronize를 사용했고synchronize 키워드는 수식 방법, 대상 또는 정적 방법에 사용할 수 있습니다.1.1synchronize 방법synchronize 방법의 동기화는 은식이며 바이트 코드 명령을 통해 제어할 필요가 없으며 방법의 호출과 반환 작업을 실현한다.jvm는 상수 풀 방법표의 ACC 에서SYNCHRONIZED의 접근 표지판에서 동기화 방법을 정합니다.방법 호출은 호출 명령으로 이 표지를 검사합니다. 동기화 방법이라면 실행 라인은 모니터를 가지고 있고 실행 방법을 사용합니다.1.2synchronize 코드 블록synchronize 키워드를 컴파일한 후 동기화 코드 블록의 앞뒤에 모니터와 모니터 exit 지령이 형성되며 이 지령 뒤에는reference 유형의 매개 변수가 잠기거나 잠금 해제할 대상을 가리킨다.모니터 명령을 실행할 때 대상의 자물쇠를 가져옵니다. 대상이 잠기지 않았거나 현재 라인에 그 대상의 자물쇠가 있다면 잠긴 계수기 +1입니다.모니터 xit 명령을 실행할 때 잠긴 계수기 - 1.자물쇠를 가져오는 데 실패하면 현재 라인이 막힌 상태로 들어갑니다.1.3 모니터(모니터 자물쇠/튜브)의 실현 방식.중량급 자물쇠는 모니터를 통해 이루어진다. 자물쇠의 표지 위치는 10이고 대상 머리의 바늘은 모니터 대상의 시작 주소를 가리킨다.자바 가상 기기에서 모니터는 Object 모니터가 실현한다.Openjdk-jdk8u-jdk8u\openjdk-jdk8u-jdk8u\hotspot\src\share\vm\runtime 패키지에 있습니다.
 ObjectMonitor() {
    _header       = NULL;// 
    _count        = 0;// 
    _waiters      = 0,// 
    _recursions   = 0;// 
    _object       = NULL;
    _owner        = NULL;// ObjectMonitor 
    _WaitSet      = NULL;// wait , waitset
    _WaitSetLock  = 0 ;
    _Responsible  = NULL ;
    _succ         = NULL ;
    _cxq          = NULL ;
    FreeNext      = NULL ;
    _EntryList    = NULL ;// block , entryset
    _SpinFreq     = 0 ;
    _SpinClock    = 0 ;
    OwnerIsThread = 0 ;
    _previous_owner_tid = 0;
  }

여러 라인이 같은 코드 블록에 접근할 때, 먼저 에 들어갑니다.Entry List 집합, 대상이 라인의 모니터를 획득한 후 owner 구역에 들어가서 owner 변수를 현재 라인 동료count+1로 설정합니다.wait 방법을 사용하면 현재 가지고 있는 모니터를 방출하고 owner 변수는null,count-1로 회복합니다동시에 현재 라인이waitset에 들어가서 깨어날 때까지 기다립니다.현재 라인이 실행되면 모니터를 방출하고 변수의 값을 복원합니다.
넷.jvm의 자물쇠 최적화 4.1 편향 자물쇠는 jdk1.6 이후에 도입된 최적화는 데이터가 경쟁이 없는 상황에서 동기화 원어를 없애는 데 목적을 둔다. 첫 번째로 그의 라인을 얻는 편향을 없애고 그 다음에 이 자물쇠가 다른 라인에 얻지 않으면 편향 라인은 더 이상 동기화할 필요가 없다.가상 기기에서 편향 자물쇠를 사용하면 자물쇠 대상이 가상 기기에서 처음 가져올 때markword의 로고 위치를 01로 설정하고 카스 조작을 사용하여markword의threadID를 업데이트합니다.다른 라인이 이 자물쇠를 가져오려고 시도할 때, 편향 모드가 끝났음을 알립니다. 자물쇠 대상이 잠겼는지 여부에 따라 편향을 취소하고 잠기지 않은 것으로 복원하거나 경량급 자물쇠로 승급합니다.
4.2 경량급 자물쇠 경량급 자물쇠는 전통적인 자물쇠 사용 운영체제의 상호 배척량에 비해 전통적인 자물쇠 사용 운영체제의 상호 배척량의 성능 소모를 줄이기 위한 것이다.코드가 동기화 블록에 들어갈 때, 이 동기화 대상이 잠겨 있지 않으면, 현재 스레드는 창고 프레임에 잠금 기록이라는 공간 (lock record) 을 만들어서 현재 대상의mark word 복사를 저장합니다.그런 다음 가상 머신 CAS는 마크 워드를 lock record를 가리키는 포인터로 업데이트합니다.업데이트 작업이 성공하면, 이 라인은 대상의 자물쇠를 가지고 있습니다.또한markword 잠금 표지의 위치를'00'으로 바꾸면 이 대상이 경량급 잠금 상태에 있음을 나타낸다.업데이트 작업이 실패하면 가상 기기는 먼저 대상의 Markword가 현재 라인의 창고 프레임을 가리키는지 검사한다. 만약에 현재 라인이 이 대상의 자물쇠를 가지고 있다는 것만 설명하면 동기화 블록에 들어가서 실행할 수 있다. 그렇지 않으면 이 자물쇠가 점령되었다는 것을 의미한다. 경량급 자물쇠는 중량급 자물쇠로 팽창해야 한다.markword의 표지 위치는 10.경량급 잠금 해제 과정도 CAS를 통해 이루어진다. 만약에 대상의markword가 여전히 라인의 잠금 기록을 가리키면 카스 조작으로 대상의 현재markword와 창고 프레임에 부여된 값의markword를 교체한다. 만약에 교체가 실패하면 다른 라인이 이 이 잠금을 얻으려고 시도하면 잠금을 풀면서 걸린 라인을 깨워야 한다.
오.java 자물쇠 업그레이드의 원리: 미완성.

좋은 웹페이지 즐겨찾기