JAVA/포스팅

자바 쓰레드 Lock

짜집퍼박사(짜박) 2023. 11. 22. 00:48

자바에서 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