ReentrantReadWriteLock — 재진입 가능한 읽기·쓰기 락
ReentrantReadWriteLock — 재진입 가능한 읽기·쓰기 락
ReentrantReadWriteLock은 ReentrantLock과 유사한 의미론을 지원하는 ReadWriteLock의 구현이에요. 이 클래스는 다음과 같은 특성을 가져요.
본문
획득 순서 (Acquisition order)
이 클래스는 락 접근에 대해 읽기·쓰기 선호 순서를 강제하지 않지만, 선택적인 공정(fairness) 정책을 지원해요.
- 비공정 모드(기본값) — 읽기·쓰기 락 진입 순서가 지정되지 않아요. 계속 경쟁하는 비공정 락은 하나 이상의 스레드를 무기한 미루게 할 수 있지만, 보통 공정 락보다 처리량이 높아요.
- 공정 모드 — 대략적인 도착 순서 정책으로 경쟁해요. 현재 락이 해제되면 가장 오래 기다린 단일 쓰기 스레드에 쓰기 락이 주어지거나, 모든 대기 쓰기 스레드보다 오래 기다린 읽기 그룹에 읽기 락이 주어져요.
공정 읽기 락을 (비재진입으로) 획득하려는 스레드는 쓰기 락이 잡혀 있거나 대기 쓰기 스레드가 있으면 블로킹돼요. 공정 쓰기 락을 획득하려는 스레드는 읽기·쓰기 락이 모두 자유일 때만 성공해요. (비블로킹 tryLock() 메서드는 이 공정 설정을 따르지 않고 가능하면 즉시 획득해요.)
재진입 (Reentrancy)
이 락은 ReentrantLock 스타일로 읽기·쓰기 락을 재획득하는 것을 허용해요. 비재진입 읽기 스레드는 쓰기 스레드가 보유한 모든 쓰기 락이 해제될 때까지 허용되지 않아요. 또한 쓰기는 읽기 락을 획득할 수 있지만 그 반대는 불가능해요. 읽기 스레드가 쓰기 락을 획득하려 하면 절대 성공하지 못해요.
락 다운그레이드 (Lock downgrading)
재진입은 쓰기 락에서 읽기 락으로 다운그레이드를 허용해요 — 쓰기 락 획득 → 읽기 락 획득 → 쓰기 락 해제 순서로요. 그러나 읽기 락에서 쓰기 락으로의 업그레이드는 불가능해요.
인터럽트 & Condition
읽기·쓰기 락 모두 획득 중 인터럽트를 지원해요. 쓰기 락은 Condition을 제공하는데, ReentrantLock.newCondition()이 ReentrantLock에 대해 제공하는 것과 동일하게 동작해요. 이 Condition은 쓰기 락에서만 쓸 수 있어요. 읽기 락은 Condition을 지원하지 않아서 readLock().newCondition()은 UnsupportedOperationException을 던져요.
계측 (Instrumentation)
이 클래스는 락이 잡혀 있는지, 경쟁 중인지 판단하는 메서드를 지원해요. 이 메서드들은 시스템 상태 모니터링용으로 설계됐지 동기화 제어용이 아니에요.
구현 참고
이 락은 최대 65535개의 재귀 쓰기 락과 65535개의 읽기 락을 지원해요. 이 한도를 초과하려 하면 락 메서드에서 Error를 던져요.
생성자
ReentrantReadWriteLock() — 기본(비공정) 순서 속성으로 생성해요.
ReentrantReadWriteLock(boolean fair) — 주어진 공정성 정책으로 생성해요.
락 획득 메서드
WriteLock writeLock() — 쓰기에 사용되는 락을 반환해요.
ReadLock readLock() — 읽기에 사용되는 락을 반환해요.
상태 모니터링 메서드
final boolean isFair() — 이 락이 공정성 설정이 true인지 반환해요.
protected Thread getOwner() — 쓰기 락을 현재 소유한 스레드를 반환해요. 소유하지 않으면 null이에요.
int getReadLockCount() — 이 락에 대해 보유된 읽기 락 수를 조회해요.
boolean isWriteLocked() — 어떤 스레드가 쓰기 락을 보유 중인지 조회해요.
boolean isWriteLockedByCurrentThread() — 현재 스레드가 쓰기 락을 보유 중인지 조회해요.
int getWriteHoldCount() — 현재 스레드의 재진입 쓰기 락 보유 수를 반환해요.
int getReadHoldCount() — 현재 스레드의 재진입 읽기 락 보유 수를 반환해요.
final boolean hasQueuedThreads() — 읽기·쓰기 락을 획득하려 기다리는 스레드가 있는지 조회해요.
final boolean hasQueuedThread(Thread thread) — 주어진 스레드가 락을 기다리는지 조회해요.
final int getQueueLength() — 락을 기다리는 스레드 수의 추정치를 반환해요.
protected Collection<Thread> getQueuedThreads() — 락을 기다릴 수 있는 스레드 컬렉션을 반환해요.
boolean hasWaiters(Condition condition) — 쓰기 락과 연관된 주어진 condition에서 기다리는 스레드가 있는지 조회해요.
int getWaitQueueLength(Condition condition) — 주어진 condition에서 기다리는 스레드 수의 추정치를 반환해요.
String toString() — 이 락과 락 상태를 식별하는 문자열을 반환해요.
더 알아보기 (Learn more)
- ReadWriteLock 인터페이스 — 이 클래스가 구현하는 인터페이스
- ReentrantLock 클래스 — 같은 의미론의 배타 락
- Java 공식 API