자바에서 Lock 인터페이스는 명시적인 락 제어를 위한 메커니즘을 제공합니다. Lock 인터페이스를 구현한 구현체 중 가장 일반적인 것은 ReentrantLock 클래스입니다. ReentrantLock은 재진입이 가능한 락을 제공하여 동일한 쓰레드가 이미 획득한 락을 다시 획득할 수 있게 합니다.
ReentrantLock 사용 예제
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Example {
private final Lock lock = new ReentrantLock();
public void performTask() {
lock.lock(); // 락 획득
try {
// 보호되어야 하는 임계 영역
// ...
} finally {
lock.unlock(); // 락 해제
}
}
}
- lock() 메서드는 락을 획득하고, unlock() 메서드는 락을 해제합니다. unlock()은 반드시 try-finally 블록에서 호출되어야 합니다. 이렇게 하는 이유는 임계 영역에서 예외가 발생했을 때도 락이 올바르게 해제되도록 하기 위함입니다.
- ReentrantLock은 tryLock() 메서드도 제공하는데, 이는 락을 획득하려 시도하며, 다른 쓰레드에 의해 이미 획득되었으면 대기하지 않고 즉시 false를 반환합니다. 획득에 성공하면 true를 반환합니다.
- 락은 반드시 unlock() 메서드로 해제되어야 하며, 해제하지 않은 상태에서 다른 쓰레드가 이 락을 획득하려고 하면 데드락이 발생할 수 있습니다.
ReentrantLock의 특징
1. 재진입이 가능한 락(Reentrant) : 동일한 쓰레드가 이미 획득한 락을 다시 획득할 수 있습니다. 이는 일부 상황에서 유용할 수 있습니다.
2. 공정성 설정 가능 : ReentrantLock은 생성자에서 공정성 여부를 설정할 수 있습니다. 공정한 락은 대기 중인 쓰레드 중에서 가장 오랫동안 대기한 쓰레드에게 락을 부여하는 방식으로 동작합니다.
3. 조건 변수(Condition) 지원 : ReentrantLock은 Condition 객체를 생성하여 여러 쓰레드 간의 통신을 가능하게 합니다.
4. 인터럽트 지원 : lockInterruptibly() 메서드를 사용하면 인터럽트에 의해 블록된 쓰레드를 깨우는 것이 가능합니다.
락의 사용은 잘못된 사용으로 인해 데드락과 같은 문제가 발생할 수 있으므로 주의해서 사용해야 합니다. 관례적으로 lock()과 unlock()은 반드시 try-finally 블록 내에서 사용하여 락의 안전한 해제를 보장합니다.
With ChatGPT
'JAVA > 포스팅' 카테고리의 다른 글
자바 쓰레드 Condition을 이용한 동기화 (0) | 2023.11.22 |
---|---|
자바 쓰레드 Lock을 이용한 동기화 (0) | 2023.11.22 |
자바 쓰레드 notify() (0) | 2023.11.22 |
자바 쓰레드 wait() (0) | 2023.11.22 |
자바 쓰레드 synchronized를 이용한 동기화 (0) | 2023.11.21 |