데이터를 동시에 공유하고 일관성을 보장하기 위한 도구로서 잠금은 JAVA 플랫폼에서 여러 구현을 갖습니다(예: 동기화 및 ReentrantLock 등). 이미 작성된 이러한 잠금은 개발에 편의를 제공하지만 잠금의 구체적인 특성과 유형은 거의 언급되지 않습니다. 이 기사 시리즈에서는 JAVA의 일반적인 잠금 이름과 특성을 분석하여 질문에 답변합니다.
4. 재진입 잠금:
이 기사에서는 JAVA의 ReentrantLock뿐만 아니라 넓은 의미의 재진입 잠금에 대해 설명합니다.
재진입 잠금(재진입 잠금)은 동일한 스레드의 외부 함수가 잠금을 획득한 후에도 내부 재귀 함수가 여전히 잠금을 획득할 코드를 갖고 있지만 영향을 받지 않음을 의미합니다.
JAVA 환경에서는 ReentrantLock과 동기화가 모두 재진입 잠금입니다.
사용 예는 다음과 같습니다.
다음과 같이 코드 코드를 복사합니다.
공개 클래스 테스트는 Runnable을 구현합니다.
공개 동기화 무효 get(){
System.out.println(Thread.currentThread().getId());
세트();
}
공개 동기화 무효 세트(){
System.out.println(Thread.currentThread().getId());
}
@보수
공개 무효 실행() {
얻다();
}
공개 정적 무효 메인(String[] args) {
테스트 ss=new Test();
새로운 스레드(ss).start();
새로운 스레드(ss).start();
새로운 스레드(ss).start();
}
}
두 예제의 최종 결과는 모두 정확합니다. 즉, 동일한 스레드 ID가 두 번 연속으로 출력됩니다.
결과는 다음과 같습니다.
다음과 같이 코드 코드를 복사합니다.
스레드 수: 8
스레드 수: 8
스레드 수: 10
스레드 수: 10
스레드 수: 9
스레드 수: 9
재진입 잠금의 가장 큰 역할은 교착 상태를 방지하는 것입니다.
스핀락을 예로 들어보겠습니다.
다음과 같이 코드 코드를 복사합니다.
공개 클래스 SpinLock {
private AtomicReference<Thread> 소유자 =new AtomicReference<>();
공개 무효 잠금(){
스레드 전류 = Thread.currentThread();
while(!owner.compareAndSet(null, 현재)){
}
}
공개 무효 잠금 해제 (){
스레드 전류 = Thread.currentThread();
owner.compareAndSet(현재, null);
}
}
스핀 잠금의 경우:
1. 동일한 스레드가 lock()을 두 번 호출하면 잠금 위치가 두 번째로 호출되어 교착 상태가 발생하면 잠금이 재진입되지 않음을 의미합니다. (잠금 기능에서는 해당 스레드가 잠금을 획득한 스레드인지 확인해야 합니다)
2. 문제 1이 해결되면 Unlock()이 처음 호출될 때 잠금이 해제됩니다. 잠금은 실제로 해제되어서는 안 됩니다.
(통계를 위해 계산 시간을 사용)
수정 후 다음과 같습니다.
다음과 같이 코드 코드를 복사합니다.
공개 클래스 SpinLock1 {
private AtomicReference<Thread> 소유자 =new AtomicReference<>();
개인 정수 개수 =0;
공개 무효 잠금(){
스레드 전류 = Thread.currentThread();
if(현재==owner.get()) {
카운트++;
반품 ;
}
while(!owner.compareAndSet(null, 현재)){
}
}
공개 무효 잠금 해제 (){
스레드 전류 = Thread.currentThread();
if(현재==owner.get()){
if(개수!=0){
세다--;
}또 다른{
owner.compareAndSet(현재, null);
}
}
}
}
이 스핀 잠금은 재진입 잠금입니다.