자바 자물쇠의 자물쇠 상세 정보
1. 자전거 자물쇠
자전거 자물쇠는 현재 라인이 끊임없이 순환 체내에서 실행되도록 하는 것으로 순환의 조건이 다른 라인이 바뀔 때 임계 구역에 들어갈 수 있다.아래와 같다
public class SpinLock {
private AtomicReference<Thread> sign =new AtomicReference<>();
public void lock(){
Thread current = Thread.currentThread();
while(!sign .compareAndSet(null, current)){
}
}
public void unlock (){
Thread current = Thread.currentThread();
sign .compareAndSet(current, null);
}
}
CAS 원자 조작을 사용하여lock 함수는 owner를 현재 라인으로 설정하고 원래의 값이 비어 있음을 예측합니다.unlock 함수는 owner를null로 설정하고 예측값은 현재 라인입니다.두 번째 스레드가 lock 동작을 호출할 때 owner 값이 비어 있지 않기 때문에 순환이 계속 실행됩니다. 첫 번째 스레드가 unlock 함수를 호출해서 owner를null로 설정해야 두 번째 스레드가 임계 구역에 들어갈 수 있습니다.
자전거 자물쇠는 현재 라인을 끊임없이 순환체로 실행하고 라인 상태를 바꾸지 않기 때문에 응답 속도가 더욱 빠르다.그러나 스레드 수가 끊임없이 증가할 때 성능이 현저히 떨어진다. 왜냐하면 모든 스레드가 실행되어야 하기 때문에 CPU 시간을 차지하기 때문이다.만약 라인 경쟁이 치열하지 않고 잠긴 시간대를 유지한다면.자전거 자물쇠를 사용하기에 적합하다.
주: 이 예는 비공평한 자물쇠입니다. 자물쇠를 획득하는 선후 순서는 락에 들어가는 선후 순서에 따라 진행되지 않습니다.
2. 자물쇠의 다른 종류
위에서 언급한 바와 같이 자전거 자물쇠는 자전거 자물쇠에서 세 가지 흔히 볼 수 있는 자물쇠 형식이 있다. 그것이 바로 TicketLock, CLHlock과 MCSlock이다.
Ticket 자물쇠는 주로 방문 순서의 문제를 해결하고 주요 문제는 다중 핵 cpu에 있다.
package com.alipay.titan.dcc.dal.entity;
import java.util.concurrent.atomic.AtomicInteger;
public class TicketLock {
private AtomicInteger serviceNum = new AtomicInteger();
private AtomicInteger ticketNum = new AtomicInteger();
private static final ThreadLocal<Integer> LOCAL = new ThreadLocal<Integer>();
public void lock() {
int myticket = ticketNum.getAndIncrement();
LOCAL.set(myticket);
while (myticket != serviceNum.get()) {
}
}
public void unlock() {
int myticket = LOCAL.get();
serviceNum.compareAndSet(myticket, myticket + 1);
}
}
매번 서비스Num 서비스 번호를 조회해서 성능에 영향을 줍니다. (메인 메모리에서 읽고 다른 cpu 수정을 막아야 합니다.)CLHLock과 MCSLock은 두 가지 유형이 비슷한 공평한 자물쇠로 체인 테이블 형식으로 정렬된다.
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
public class CLHLock {
public static class CLHNode {
private volatile boolean isLocked = true;
}
@SuppressWarnings("unused")
private volatile CLHNode tail;
private static final ThreadLocal<CLHNode> LOCAL = new ThreadLocal<CLHNode>();
private static final AtomicReferenceFieldUpdater<CLHLock, CLHNode> UPDATER = AtomicReferenceFieldUpdater.newUpdater(CLHLock.class,
CLHNode.class, "tail");
public void lock() {
CLHNode node = new CLHNode();
LOCAL.set(node);
CLHNode preNode = UPDATER.getAndSet(this, node);
if (preNode != null) {
while (preNode.isLocked) {
}
preNode = null;
LOCAL.set(node);
}
}
public void unlock() {
CLHNode node = LOCAL.get();
if (!UPDATER.compareAndSet(this, node, null)) {
node.isLocked = false;
}
node = null;
}
}
CLHlock은 NUMA 아키텍처에서 사용할 수 없는 쿼리 선행 변수입니다. (이 아키텍처에서는 각 스레드가 서로 다른 물리적 메모리 영역에 분포되어 있습니다.)MCSLock은 로컬 변수의 노드를 순환합니다.CLHlock 문제가 없습니다.
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
public class MCSLock {
public static class MCSNode {
volatile MCSNode next;
volatile boolean isLocked = true;
}
private static final ThreadLocal<MCSNode> NODE = new ThreadLocal<MCSNode>();
@SuppressWarnings("unused")
private volatile MCSNode queue;
private static final AtomicReferenceFieldUpdater<MCSLock, MCSNode> UPDATER = AtomicReferenceFieldUpdater.newUpdater(MCSLock.class,
MCSNode.class, "queue");
public void lock() {
MCSNode currentNode = new MCSNode();
NODE.set(currentNode);
MCSNode preNode = UPDATER.getAndSet(this, currentNode);
if (preNode != null) {
preNode.next = currentNode;
while (currentNode.isLocked) {
}
}
}
public void unlock() {
MCSNode currentNode = NODE.get();
if (currentNode.next == null) {
if (UPDATER.compareAndSet(this, currentNode, null)) {
} else {
while (currentNode.next == null) {
}
}
} else {
currentNode.next.isLocked = false;
currentNode.next = null;
}
}
}
코드상 CLH는 MCS보다 간단합니다.CLH의 대기열은 암시적인 대기열로 실제 후계 결점 속성이 없습니다.
MCS의 대기열은 실제 후계 결점 속성이 있는 현식 대기열입니다.
JUC ReentrantLock의 기본 내부에 사용되는 자물쇠는 CLH 자물쇠입니다. (개선된 점이 많습니다. 자전거 자물쇠를 차단 자물쇠로 바꾸는 등등)
(전문 끝)
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.