[JDK] JDK 소스 코드 분석 -AbstractQueuedSynchronizer (1)

개요

 

전술 한 " JDK 소스 코드 분석 -Lock 및 조건 "잠금 인터페이스의 간략한 분석, 주로 JDK ReentrantLock와의 구현 클래스는 ( "재입 잠금"으로 번역 될 수 있습니다.) ReentrantLock와 구현은 그 내부 동기화를 중첩 클래스 의존하고, 또한합니다 (AQS라고 함) AbstractQueuedSynchronizer의 동기화에서 상속. 또한, 등 CountDownLatch를,으로 CyclicBarrier, 같은 다른 도구들에 의해 복잡뿐만 아니라 ReentrantLock와는도 실현 AQS 클래스를 기반으로합니다. AQS는 많은 클래스의 초석과 계약으로 이해 될 수있다. 따라서, 분석 및 계약 이행 원칙 이전에 일반적으로 클래스에서 사용되는, AQS, 다시 분석 한 후 시간이 많이 간단하게 될 것입니다 방법을 이해하는 것이 필요하다.

 

AQS 내핵 변수 상태를 갖는다 또한, 노드 클래스 노드는 두 개의 큐를 유지하고, 메인 큐 (주 큐) 큐 상태 (상태 큐), 간략화를 위해, 각각 하나의 이중 연결리스트 등을 모두 이해 될 .

 

AQS는 AQS에 의해 제공되는 인프라의 "게임의 규칙"자신을 개발하는 모든 다른 일반적으로 사용되는 클래스 ReentrantLock와, 해, CountDownLatch 및 기타 내부 중첩 클래스 동기화와 같은 인프라의 세트와 같은 장치를 제공하고 생산 다른 제품. 그리고 그들은 게임의 규칙은 두 큐는 상태 변수 주위에 작동합니다.

 

PS : 자세한 AQS 내용으로하고, 그러므로 점의 기사, 그 전체의 글 먼저 개요를 분석 할 계획이다.

 

코드 분석

 

AQS 클래스 서명 :

공공  추상  클래스 AbstractQueuedSynchronizer의는
     확장 AbstractOwnableSynchronizer이
     구현 의 java.io.Serializable을 {}
이 직접 추상 클래스를 인스턴스화 할 수 있습니다 볼 수 있습니다. 다음과 같이 주요 코드는 부모를 AbstractOwnableSynchronizer :
공공  추상  클래스 AbstractOwnableSynchronizer는
     구현 의 java.io.Serializable를 { 

    / ** 
     * 전용 모드 동기화의 현재 소유자. 
     * / 
    개인  과도 스레드 exclusiveOwnerThread; 
    
    // 其他代码 
}

주요 내부는 분석에 관해서 소유자 역할은 나중에 후 전용 모드에서 스레드를 표시하는 것입니다, 그리고 변수 exclusiveOwnerThread을 유지합니다.

 

상자의 클래스

 

AQS 각각 두 개의 내부 중첩 클래스를 가지며, 노드 ConditionObject가.

노드 클래스 코드는 다음과 같이 :

정적  최종  클래스 노드 {
     // 공유 모드 
    정적  최종 노드 공유 = 새로운 새로운 노드 ();
     // 단독 모드 
    정적  최종 노드 배타적 = 널 (null) ; 
    
    // 여러 국가가 waitStatus 
    정적  최종  INT 취소됨 = 1. ,
     정적  최종  INT SIGNAL (신호) = - . (1) ,
     정적  최종  INT의 상태 = -2 ;
     정적  최종  INT의 전파 = -3 ;
     휘발성  INT waitStatus;

    // 선행 노드 (마스터 큐) 
    휘발성 노드 PREV;
     // 후임 노드 (주 큐) 
    휘발성 노드 다음;
     // 스레드 노드 
    휘발성 스레드 스레드;
     // 후임 노드 (조건 대기열) 
    노드 nextWaiter; 

    최종  부울 isShared () {
         반환 nextWaiter가 == 상기 SHARED을 
    } 

    최종 ) (노드 전신을 발생 NullPointerException이 { 
        노드 P = ; PREV
         IF (P == )
             드로  새로운 새 NullPointerException이 ();
         를 다른
            반환 P는; 
    } 

    노드 () {     // 초기 SHARED 마커 헤드 또는 설정하는 데 사용 
    } 
    {기지국 (스레드 나사, 기지국 모드)      // addWaiter 의해 사용 
         .nextWaiter = 모드;
         .thread = 스레드; 
    } 

    노드 (스레드 스레드, int로 waitStatus를) { // 조건에서 사용 
         .waitStatus = waitStatus;
         .thread = 스레드; 
    } 
}

제 생성자를 사용하여 메인 큐에 추가 노드 클래스 스레드 스레드의 패키지로 이해 될 수있다. 따라서, 노드와 큐 메인 큐에서 하나 개의 모드 (MODE), 상태 (waitStatus) 스레드가 있음을 알 수있다.

 

상자의 클래스의 ConditionObject가 :

공공  클래스 ConditionObject가이 구현 조건, java.io.Serializable을 {
     / ** 상태 큐의 첫 번째 노드를. * / 
    개인  과도 노드 firstWaiter; 
    
    / ** 상태 큐의 마지막 노드입니다. * / 
    개인  과도 노드 lastWaiter;
    // ... 
}

조건 ConditionObject가이 큐의 주요 작동 조건 인 인터페이스를 구현, 여기에만 클래스 서명은 나중에 다시 분석을 사용 특히, 머리와 꼬리 노드에 부착.

 

주요 변수

 

AQS 코드는 긴하지만, 다음과 같이는 멤버 변수의 대부분을 가지고 있지 않습니다

// 마스터 노드 큐 헤드 
개인  과도  휘발성 노드 머리; 

// 메인 큐 꼬리 노드 
개인  과도  휘발성 노드 꼬리; 

// 상태, 핵심 변수 AQS 유지하기 위해 
개인  휘발성  INT의 상태;

메인 헤드와 테일 큐의 머리와 꼬리 노드 AQS 가변 상태 유지의 코어 및 ReentrantLock와 클래스의 클래스 등 동기화를 구현하며, 각각의 기능이 동작 상태에 의해 달성된다.

 

CAS 작업

 

내부 AQS는 CAS의 일련의 (비교 및 스왑) 작업이 안전하지 않은 카테고리별로 (CAS가 더 이상 여기에 자신의 검색 이해 될 수있다 개념을 설명 없음) 달성 :

// 안전하지 않은 예 얻기 
개인  정적  최종 안전하지 않은 안전하지 않은 = ; Unsafe.getUnsafe ()
 // 메모리 오프셋 상태, 머리, 꼬리 주소 변수 
개인  정적  최종  stateOffset,
 개인  정적  최종  headOffset,
 개인  정적  최종  tailOffset,
 개인  정적  최종  waitStatusOffset,
 개인  정적  최종  nextOffset,
 정적 {
     은 try { 
        stateOffset =unsafe.objectFieldOffset 
            (. AbstractQueuedSynchronizer의 클래스 .getDeclaredField ( "상태" )); 
        headOffset = unsafe.objectFieldOffset 
            (. AbstractQueuedSynchronizer의 클래스 .getDeclaredField ( "헤드" )); 
        tailOffset = unsafe.objectFieldOffset 
            (. AbstractQueuedSynchronizer의 클래스 .getDeclaredField ( "꼬리" )); 
        waitStatusOffset = unsafe.objectFieldOffset 
            (. 노드 클래스 .getDeclaredField ( "waitStatus" )); 
        nextOffset =unsafe.objectFieldOffset 
            (. 노드 클래스 .getDeclaredField ( "다음" )); 
    } 캐치 (예외 예) { 던질  새로운 오류 (예)를; } 
} 

// 一些CAS操作
민간  최종  부울 compareAndSetHead (노드 업데이트) {
     반환 unsafe.compareAndSwapObject (  , headOffset, , 업데이트) 
} 

민간  최종  부울 compareAndSetTail (노드는 노드 업데이트, 기대) {
     반환 unsafe.compareAndSwapObject을 ( , tailOffset은, 갱신, 기대); 
}

개인  정적  최종  부울 compareAndSetWaitStatus (노드 노드,
                                                      INT가 기대
                                                      INT의 갱신) {
     반환 (노드가 waitStatusOffset는, unsafe.compareAndSwapInt이 
                                    기대 갱신) 
} 

개인  정적  최종  부울 compareAndSetNext (노드 노드, 
                                               노드가 기대 
                                               노드 갱신) { 
    반환 (노드가 nextOffset이 기대 갱신) unsafe.compareAndSwapObject가; 
}

내부 스레드 안전 AQS 작업의 대부분은 CAS를 통해 이루어진다.

 

개요

 

1. AQS 인스턴스를 직접 생성 할 수없는 추상 클래스입니다;

2. AQS 내부 코어는 가변 상태뿐만 아니라, 두 개의 큐를 유지하고, 메인 큐 (큐 주) 큐 상태 (상태 큐);

클래스 동기화 내에 중첩 및 동기화 클래스에서 자신의 "게임의 규칙"을 개발하여 3 AQS 인프라의 세트를 제공, ReentrantLock와 AQS 및 다른 클래스는 일반적으로 상속됩니다.

 

이 문서에서는 AQS는 다음 구현 원리에 대한 자세한 분석을 따라 개요를 제공합니다. 또한,이 상태 가변형 긴 INT 별도로 분석되지 AQS의 형태 인 것을 제외하고는, AQS와 실질적으로 동일한 클래스 AbstractQueuedLongSynchronizer이있다.

 

PS : 다음 링크에서도 좋은 기록 된 여러 기사가 있습니다 :

https://www.cnblogs.com/liuyun1995/p/8400663.html

 

 

배고픈 그대로, 어리석은있어.

PS :이 문서는 제 WriteOnRead [] 공용 마이크로 채널 번호에서 나타났다.

추천

출처www.cnblogs.com/jaxer/p/11297652.html