데이터를 동시에 공유하고 일관성을 보장하기 위한 도구로서 잠금은 JAVA 플랫폼에서 여러 구현을 갖습니다(예: 동기화 및 ReentrantLock 등). 이미 작성된 이러한 잠금은 개발에 편의를 제공하지만 잠금의 구체적인 특성과 유형은 거의 언급되지 않습니다. 이 기사 시리즈에서는 JAVA의 일반적인 잠금 이름과 특성을 분석하여 질문에 답변합니다.
차단 잠금
차단 잠금은 스핀 잠금과 달리 스레드의 실행 상태를 변경합니다.
JAVA 환경에서 Thread 스레드는 다음과 같은 상태를 갖습니다.
1. 새로운 상태
2. 준비 상태
3. 운전상태
4. 차단된 상태
5. 사망 상태
블로킹 잠금은 스레드가 블로킹 상태에 들어가서 대기하도록 허용한다고 할 수 있습니다. 해당 신호(wake-up, 시간)를 얻으면 스레드는 준비 상태에 있는 모든 스레드가 실행 상태로 들어갈 수 있습니다. 경쟁을 통해.
JAVA에서 진입/종료, 상태 차단 또는 차단 잠금을 포함할 수 있는 메소드에는 동기화 키워드(중 가중치 잠금), ReentrantLock, Object.wait()/notify(), LockSupport.park()/unpart()( juc이 자주 사용됨)
다음은 JAVA 차단 잠금의 예입니다.
패키지 잠금; 가져오기 java.util.concurrent.atomic.AtomicReferenceFieldUpdater; 가져오기 java.util.concurrent.locks.LockSupport; 공개 클래스 CLHLock1 { 공개 정적 클래스 CLHNode { 비공개 휘발성 스레드 isLocked } @SuppressWarnings("사용되지 않음") 비공개 휘발성 CLHNode tail; static final ThreadLocal<CLHNode> LOCAL = 신규 ThreadLocal<CLHNode>(); private static final AtomicReferenceFieldUpdater<CLHLock1, CLHNode> UPDATER = AtomicReferenceFieldUpdater.newUpdater(CLHLock1.class, CLHNode.class, "tail") { CLHNode node = new CLHNode(); .set(노드); preNode = UPDATER.getAndSet(this, node); if (preNode != null) { preNode.isLocked = Thread.currentThread(); preNode = null } } 공개 void Unlock() { CLHNode 노드 = LOCAL.get(); if (!UPDATER.compareAndSet(this, node, null)) { System.out.println("unlock/t" + node.isLocked.getName()) LockSupport.unpark(node.isLocked) } node = null;
여기서는 LockSupport.unpark()의 차단 잠금을 사용합니다. 이 예는 CLH 잠금에서 수정되었습니다.
차단 잠금의 장점은 차단된 스레드가 CPU 시간을 차지하지 않고 과도한 CPU 점유를 유발하지 않지만 진입 시간과 복구 시간이 스핀 잠금보다 약간 느리다는 것입니다.
치열한 경쟁의 경우, 스핀락에 비해 블로킹락의 성능이 월등히 높다.
이상적인 상황은 스레드 경쟁이 치열하지 않을 때 스핀 잠금을 사용하고 경쟁이 치열할 때 차단 잠금을 사용하는 것입니다.
(전체 텍스트 끝)