![ReentrantLock - Lock 획득을 위해 대기중인 Thread에 Interrupt 호출이 안먹힐 때](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FI2xjS%2FbtsG5tzoM5y%2FSbdmCwwtx4vPHVC1wcdmIK%2Fimg.png)
ReentrantLock - lockInterruptibly()
특정 Thread에서 Lock 획득을 위해lock.lock()을 호출했을 때 다른 스레드에 의해 이미 Lock이 점유되어 있는 상황에서
현재 Thread는 Lock이 해제되는걸 기다리기 위해 무한 대기 상태에 걸려 있습니다. (Blocking 상태)
이때 대기 상태를 해제하기 위해 Thread를 Interrupt를 시켰는데 Interrupt 호출이 되지 않아서, 알아보고 해결한 방법을 기록합니다.
아래 예시 코드로 설명해보겠습니다.
lockInterruptibly()를 사용해야 하는 이유 - 예시 코드
@Override
public void run() {
lock.lock(); // Lock 획득 실패 - 다른 스레드에서 사용 중
// ...
if (Thread.currentThread().isInterrupted()) {
cleanUpAndExit();
}
}
위 예시 코드에서 Lock 획득 대기 상태를 풀기 위해 Thread.interrupt()를 호출해도
lock() 함수는 InterruptedException 상태를 무시
하므로, Lock 획득을 위해 대기중인 현재 Thread에 Interrupt를 호출해도 먹히지 않으며,
Thread Interrupt 상태에 대한 처리가 불가능 해집니다.
그래서 interrupt 상태에 대한 세밀한 제어를 하려면 lockInterruptibly()를 사용하거나, tryLock 함수로 시간 제한을 두고 잠금을 시도하는 방법이 있습니다.
2가지 방법 중 lockInterruptibly() 함수를 이용한 방법을 알아보겠습니다.
lock.lock() 대신 lock.lockInterruptibly()를 사용
현재 스레드가 인터럽트(interrupt) 상태일 때 대기 상태에 들어가는 대신 InterruptedException을 던짐으로써,
현재 스레드가 블럭(block)되지 않도록 할 수 있습니다.
이를 통해, 다른 스레드가 현재 스레드를 인터럽트할 때 즉각적으로 대응할 수 있으며,
대기 상태에 있던 스레드가 대기상태를 벗어나 Interrupt 호출에에 응답하여 예외 처리 루틴을 실행할 수 있습니다.
try-catch 블록에서 try로 lockInterruptibly()를 호출하고 대기상태일떄 Interrupt를 호출하면 InterruptedException에 대한 처리가 가능합니다.
@Override
public void run() {
try {
lock.lockInterruptibly(); // 이제 InterruptedException에 반응할 수 있음
// ...
if (Thread.currentThread().isInterrupted()) {
cleanUpAndExit();
}
} catch (InterruptedException e) {
// 인터럽트 발생 시 cleanUpAndExit 호출
cleanUpAndExit();
} finally {
// 락을 성공적으로 획득했으면 해제
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
'📘 Backend > Concurrency' 카테고리의 다른 글
ReentrantReadWriteLock - ReadLock & WriteLock을 사용한 Read Thread 성능 향상 (2) | 2024.05.03 |
---|---|
Atomic Operation & volatile & Metrics (0) | 2024.01.06 |
Critical Section & Synchronized with Lock (2) | 2024.01.06 |
Thread 간 Resource 공유 시 발생할 수 있는 문제 (2) | 2024.01.06 |
ReentrantLock을 이용한 Thread 동기화 (2) | 2023.12.26 |
열심히 살고 싶은 사람의 메모장
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!