자바 병발 J.U.C 의 AQS:CLH 동기 화 대기 열
CLH 동기 화 대기 열 에서 한 노드 는 하나의 스 레 드 를 표시 합 니 다.스 레 드 의 참조(thread),상태(wait Status),전구 노드(prev),후계 노드(next)를 저장 하고 있 습 니 다.그 정 의 는 다음 과 같 습 니 다.
static final class Node {
/** */
static final Node SHARED = new Node();
/** */
static final Node EXCLUSIVE = null;
/**
* , , , ;
*/
static final int CANCELLED = 1;
/**
* , , ,
*/
static final int SIGNAL = -1;
/**
* , Condition , Condition signal() , ,
*/
static final int CONDITION = -2;
/**
*
*/
static final int PROPAGATE = -3;
/** */
volatile int waitStatus;
/** */
volatile Node prev;
/** */
volatile Node next;
/** */
volatile Thread thread;
Node nextWaiter;
final boolean isShared() {
return nextWaiter == SHARED;
}
final Node predecessor() throws NullPointerException {
Node p = prev;
if (p == null)
throw new NullPointerException();
else
return p;
}
Node() {
}
Node(Thread thread, Node mode) {
this.nextWaiter = mode;
this.thread = thread;
}
Node(Thread thread, int waitStatus) {
this.waitStatus = waitStatus;
this.thread = thread;
}
}
CLH 동기 화 대기 열 구성 도 는 다음 과 같 습 니 다.열거 하 다
데이터 구 조 를 배 운 우 리 는 CLH 대기 열 에 들 어 가 는 것 이 더 간단 하 다.tail 이 새로운 노드,새로운 노드 를 가리 키 는 prev 가 현재 의 마지막 노드 를 가리 키 고 현재 의 마지막 노드 의 next 는 현재 노드 를 가리킨다.코드 는 addWaiter(Node node)방법 을 볼 수 있 습 니 다.
private Node addWaiter(Node mode) {
// Node
Node node = new Node(Thread.currentThread(), mode);
//
Node pred = tail;
if (pred != null) {
node.prev = pred;
//CAS
if (compareAndSetTail(pred, node)) {
pred.next = node;
return node;
}
}
//
enq(node);
return node;
}
addWaiter(Node node)는 먼저 빠 른 시 도 를 통 해 끝 노드 를 설정 하고 실패 하면 enq(Node node)방법 으로 끝 노드 를 설정 합 니 다.
private Node enq(final Node node) {
// ,
for (;;) {
Node t = tail;
//tail ,
if (t == null) {
if (compareAndSetHead(new Node()))
tail = head;
} else {
//
node.prev = t;
if (compareAndSetTail(t, node)) {
t.next = node;
return t;
}
}
}
}
위의 코드 에서 두 가지 방법 은 모두 하나의 CAS 방법 인 compare AndSetTail(Node expect,Node update)을 통 해 끝 노드 를 설정 하 는데 이 방법 은 노드 가 안전하게 추 가 된 것 을 확보 할 수 있다.enq(Node node)방법 에서 AQS 는'죽은 순환'방식 으로 노드 를 정확하게 추가 할 수 있 도록 합 니 다.성공 적 으로 추가 한 후에 야 현재 스 레 드 가 이 방법 에서 돌아 올 수 있 습 니 다.그렇지 않 으 면 계속 실 행 될 것 입 니 다.프로 세 스 그림 은 다음 과 같 습 니 다.
열거 하 다
CLH 동기 화 대기 열 은 FIFO 를 따 릅 니 다.첫 번 째 노드 의 스 레 드 가 동기 화 상 태 를 방출 한 후에 그의 후계 노드(next)를 깨 울 것 입 니 다.그리고 후계 노드 는 동기 화 상 태 를 성공 적 으로 가 져 올 때 자신 을 첫 번 째 노드 로 설정 합 니 다.이 과정 은 매우 간단 합 니 다.head 는 이 노드 를 실행 하고 원래 노드 의 next 와 현재 노드 의 prev 를 끊 으 면 됩 니 다.이 과정 에서 CAS 를 사용 하지 않 아 도 됩 니 다.하나의 스 레 드 만 동기 화 상 태 를 성공 적 으로 얻 을 수 있 기 때 문 입 니 다.프로 세 스 그림 은 다음 과 같 습 니 다.
이상 은 본문의 전체 내용 입 니 다.여러분 의 학습 에 도움 이 되 기 를 바 랍 니 다.여러분 도 저 희 를 많이 지지 해 주시 기 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.