[자바 병발 노트]ReentrantLock 관련 정리
우리 중의 한 사람 으로서 끊 임 없 는 학습 이 필요 합 니 다.저 는 일 을 하면 서 분석 과 정리,학습 노트 를 블 로그 로 써 서 여러분 과 함께 교류 하고 이런 방식 으로 자신의 학습 여행 을 기록 하고 싶 습 니 다.
본 고 는 학습 교류 에 만 사용 되 며,권리 침 해 는 반드시 삭제 해 야 한다.상업 목적 에 사용 되 지 않 으 니 전재 할 때 출처 를 밝 혀 주 십시오.
1. ReentrantLock
4.567917.4.567914.잠 금 을 다시 넣 을 수 있 고 Lock 과 Serializable 인 터 페 이 스 를 실현 할 수 있 습 니 다
4.567917.자바 환경 에서 4.567914.와 4.567914.모두 잠 금 을 다시 넣 을 수 있 습 니 다.
4.567917.자 물 쇠 를 다시 들 어 갈 수 있 고 재 귀 자물쇠 라 고도 합 니 다.한 스 레 드 가 대상 의 자 물 쇠 를 요청 한 후에 이 대상 의 자 물 쇠 를 다시 요청 하면 이 대상 의 자 물 쇠 를 다시 얻 을 수 있 습 니 다
4.567917.4.567914 방법 을 호출 하면 같은 스 레 드 ID 가 두 번 연속 으로 출력 됩 니 다
public void get() {
lock.lock();
System.out.println(Thread.currentThread().getId());
set();
lock.unlock();
}
public void set() {
lock.lock();
System.out.println(Thread.currentThread().getId());
lock.unlock();
}
4.567917.4.567914.구조 함수 에서 두 가지 자 물 쇠 를 제공 합 니 다.공평 한 자물쇠 와 불공평 한 자 물 쇠 를 만 듭 니 다(기본 값).
public ReentrantLock() {
sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
4.567917.공평 한 자물쇠 에 스 레 드 는 그들 이 요청 한 순서에 따라 자 물 쇠 를 얻 지만 불공평 한 자물쇠 에 서 는 새치기 가 허용 된다.
4.567917.한 스 레 드 가 불공평 한 자 물 쇠 를 요청 할 때 요청 을 보 내 는 동시에 이 자 물 쇠 를 사용 가능 한 상태 로 바 꾸 면 이 스 레 드 는 대기 열 에 있 는 모든 대기 스 레 드 를 건 너 뛰 어 자 물 쇠 를 얻 을 수 있 습 니 다
4.567917.불공평 한
ReentrantLock
새치기 행 위 를 제창 하지 않 지만 특정한 스 레 드 가 적당 한 시기 에 새치기 하 는 것 을 방지 할 수 없다 4.567917.공평 한 자물쇠 에 다른 스 레 드 가 자 물 쇠 를 가지 고 있 거나 다른 스 레 드 가 대기 열 에서 이 자 물 쇠 를 기다 리 고 있다 면 새로 보 낸 요청 스 레 드 는 대기 열 에 들 어 갈 것 입 니 다.
4.567917.공평 한 자물쇠 가 아 닌 특정한 스 레 드 에 잠 겨 있 을 때 새로 요청 한 스 레 드 가 대기 열 에 들 어 갈 수 있 습 니 다
4.567917.불공 정 잠 금 성능 이 공정 잠 금 성능 보다 높 은 원인
4.567917.걸 려 있 는 스 레 드 와 이 스 레 드 의 실제 운행 사이 에 심각 한 지연 이 존재 합 니 다
4.567917.스 레 드 A 가 자 물 쇠 를 가지 고 있다 고 가정 하고 스 레 드 B 가 이 자 물 쇠 를 요청 합 니 다.자 물 쇠 는 A 가 가지 고 있 기 때문에 B 는 걸 릴 것 이다.A 가 자 물 쇠 를 풀 면 B 가 깨 어 나 기 때문에 B 는 다시 이 자 물 쇠 를 가 져 오 려 고 시도 합 니 다.이와 함께 스 레 드 C 도 이 자 물 쇠 를 요청 하면 C 는 B 가 완전히 깨 어 나 기 전에 이 자 물 쇠 를 얻 고 사용 하 며 방출 할 수 있 습 니 다.이렇게 하면 윈 윈 의 국면 이다.B 가 자 물 쇠 를 얻 는 시간 이 늦 어 지지 않 았 고 C 는 더욱 일찍 자 물 쇠 를 얻 었 으 며 스루풋 도 높 아 졌 다
4.567917.자 물 쇠 를 가 진 시간 이 상대 적 으로 길 거나 자 물 쇠 를 요청 하 는 평균 시간 간격 이 길 면 공평 한 자 물 쇠 를 사용 해 야 한다.
4.567917.이런 상황 에서 새치기 가 가 져 온 스루풋 증가(잠 금 이 사용 가능 한 상태 에 있 을 때 스 레 드 는 깨 어 나 는 과정 에 있 음)는 나타 나 지 않 을 수 있 습 니 다
1.1 공평 자물쇠 와 불공평 자물쇠 의 실현
공평자물쇠
4.567917.모든 스 레 드 가 자 물 쇠 를 가 져 오 는 과정 은 공평 합 니 다.가장 오래 기다 리 면 가장 먼저 자 물 쇠 를 깨 워 줍 니 다
static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;
final void lock() {
acquire(1);
}
/**
* Fair version of tryAcquire. Don't grant access unless
* recursive call or no waiters or is first.
*/
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
}
ReentrantLock
방법 은 불공평 자물쇠synchronized
방법 보다get()
방법 이 하나 더 많아 졌 다.public final boolean hasQueuedPredecessors() {
// The correctness of this depends on head being initialized
// before tail and on head.next being accurate if the current
// thread is first in queue.
Node t = tail; // Read fields in reverse initialization order
Node h = head;
Node s;
return h != t &&
((s = h.next) == null || s.thread != Thread.currentThread());
}
불공평 자물쇠
4.567917.공평 한 자물쇠 가 아니 라 자 물 쇠 를 얻 는 선점 체제 로 무 작위 로 자 물 쇠 를 얻 는 것 이다.공평 한 자물쇠 와 다른 것 은 먼저 자 물 쇠 를 얻 는 것 이 아니 라 이런 방식 으로 인해 일부 스 레 드 가 자 물 쇠 를 얻 지 못 할 수도 있다.결 과 는 불공평 하 다.
4.567917.불공평 한 자 물 쇠 는 스 레 드 를 배 고 프 게 할 수 있다
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
/**
* Performs lock. Try immediate barge, backing up to normal
* acquire on failure.
*/
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
4.567917.공평 한 지 여 부 는 팀 에 들 어가 기 전,팀 에 들 어간 후에 순서대로 자 물 쇠 를 얻는다
1.2 재 접속 잠 금 실현
4.567917.스 레 드 는 이미 가지 고 있 는 자 물 쇠 를 중복 으로 얻 을 수 있 습 니 다.
4.567917.불공평 과 공평 한 자물쇠 에서 모두 재 입 자 물 쇠 를 실현 했다
if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
1.3 ReentrantLock 필드 사용
장면 1:이 조작 이 실행 중인 것 을 발견 하면 실행 하지 않 습 니 다(상태 실행)
private ReentrantLock lock = new ReentrantLock();
if (lock.tryLock()) { // lock, false , 。
try {
//
} finally {
lock.unlock();
}
}
장면 2:이 동작 이 실행 중인 것 을 발견 하면 하나의 실행 을 기다 리 십시오(동기 화 실행,synchronized 와 유사)
private ReentrantLock lock = new ReentrantLock(); // false,
// private ReentrantLock lock = new ReentrantLock(true); //
try {
lock.lock(); // , ,
//
} finally {
lock.unlock();
}
4.567917.공평 한 상황 에서 조작 은 한 팀 씩 순서대로 집행 하여 집행 순 서 를 확보한다.(줄 을 서 는 데 더 많은 시간 을 소모 할 것 이다)
try {
if (lock.tryLock(5, TimeUnit.SECONDS)) { // lock, 5s, , 5s false
try {
//
} finally {
lock.unlock();
}
}
} catch (InterruptedException e) {
e.printStackTrace(); // (interrupt), InterruptedException
}
장면 4:이 조작 이 이미 실행 중인 것 을 발견 하면 실행 을 기다 리 세 요.이 때 진행 중인 작업 을 중단 하고 즉시 자 물 쇠 를 풀 고 다음 작업 을 계속 할 수 있 습 니 다.
try {
lock.lockInterruptibly();
//
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
4.567917.이런 상황 은 주로 일부 조작 이 자원 에 대한 점용 을 취소 하 는 데 사용 된다.예 를 들 어(동기 화 되 고 있 는 작업 을 취소 하여 비정 상 작업 의 장시간 점용 으로 인 한 차단 을 방지 합 니 다)이 작업 의 비용 도 매우 많 고 일반적으로 사용 하 는 것 을 권장 하지 않 습 니 다
장면 5:조건 판단.
4.567917.모든 lock 은 임의의 데이터 의 Condition 대상 을 가 질 수 있 습 니 다
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
lock.lock();
try {
while( ) {
condition.wait();
}
//
} finally {
lock.unlock();
}
1.4 ReentrantLock 의 방법
방법.
설명 하 다.
getHoldCount()
현재 스 레 드 에서 이 자 물 쇠 를 가 져 오 는 횟수 를 조회 합 니 다.이 스 레 드 는 lock 방법 을 실행 하 는 횟수 입 니 다.
getQueueLength()
이 자 물 쇠 를 가 져 오 기 를 기다 리 는 스 레 드 추정 수 를 되 돌려 줍 니 다.예 를 들 어 10 개의 스 레 드 를 시작 하고 1 개의 스 레 드 가 자 물 쇠 를 얻 습 니 다.이때 돌아 오 는 것 은 9 입 니 다.
getWaitQueueLength(Condition condition)
이 자물쇠 와 관련 된 주어진 조건 을 기다 리 는 스 레 드 추정 수 를 되 돌려 줍 니 다.예 를 들 어 10 개의 스 레 드 는 같은 condition 대상 을 사용 하고 이 10 개의 스 레 드 는 condition 대상 의 await 방법 을 실 행 했 습 니 다.그러면 이 방법 을 실행 하면 10 으로 돌아 갑 니 다.
hasWaiters(Condition condition)
이 자물쇠 와 관련 된 주어진 조건(condition)을 기다 리 는 스 레 드 가 있 는 지 확인 합 니 다.contidon 대상 을 지정 하 는 스 레 드 가 condition.awat 방법 을 얼마나 실 행 했 는 지 확인 합 니 다.
hasQueuedThread(Thread thread)
주어진 스 레 드 가 이 자 물 쇠 를 가 져 오 기 를 기다 리 고 있 는 지 확인 합 니 다.
hasQueuedThreads()
이 자 물 쇠 를 기다 리 는 스 레 드 가 있 습 니까?
isFair()
이 자 물 쇠 는 공평 한 자물쇠 입 니까?
isHeldByCurrentThread()
현재 스 레 드 가 잠 금 을 유지 할 지 여부 입 니 다.스 레 드 의 실행 lock 방법 은 각각 false 와 true 입 니 다.
isLock()
이 자물쇠 에 임의의 스 레 드 가 있 는 지 여부 입 니 다.
lockInterruptibly()
현재 스 레 드 가 중단 되 지 않 으 면 자 물 쇠 를 가 져 옵 니 다.
tryLock()
자 물 쇠 를 가 져 오 려 고 시도 합 니 다.호출 할 때 만 자 물 쇠 를 스 레 드 에 차지 하지 않 고 자 물 쇠 를 가 져 옵 니 다.
tryLock(long timeout, TimeUnit unit)
주어진 대기 시간 동안 다른 스 레 드 에 잠 겨 있 지 않 으 면 이 자 물 쇠 를 가 져 옵 니 다.
1.5 try Lock,lock,lock Interruptibly 의 차이
try Lock 은 자 물 쇠 를 얻 으 면 true 로 돌아 가 고,즉시 false 로 돌아 갈 수 없습니다.
4.567917.lock 과 lock Interruptibly 는 두 스 레 드 가 각각 이 두 가지 방법 을 실행 하면 이 두 스 레 드 를 중단 하면 전 자 는 이상 을 던 지지 않 고 후 자 는 이상 을 던 집 니 다
총화
4.567917.예 를 들 어 스 레 드 가 폐쇄 된 잠 금 대상 에 대해 최적화 를 제거 하고 잠 금 입 도 를 증가 시 켜 내 장 된 잠 금 의 동기 화 를 없앤다
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.