본문으로 건너뛰기
김신건의 로그

[Java] ReentrantReadWriteLock

· 수정 · 📖 약 1분 · 259자/단어 #java #concurrent #lock #read-write
ReentrantReadWriteLock, java.util.concurrent.locks.ReentrantReadWriteLock, RRWLock, 읽기쓰기락, ReadWriteLock

정의

java.util.concurrent.locks.ReentrantReadWriteLock읽기 락과 쓰기 락을 분리ReentrantLock 의 확장.

핵심 규칙:

  • 여러 reader 가 동시에 read lock 획득 가능 (병렬 읽기)
  • writer 는 배타적, write lock 잡혀 있으면 reader 도 새 writer 도 대기
  • 재진입 가능 (같은 스레드)

시각화

사용

ReentrantReadWriteLock rrw = new ReentrantReadWriteLock();
Lock readLock = rrw.readLock();
Lock writeLock = rrw.writeLock();

// Reader
readLock.lock();
try {
    return data.get();
} finally {
    readLock.unlock();
}

// Writer
writeLock.lock();
try {
    data.update();
} finally {
    writeLock.unlock();
}

언제 유리한가

읽기 >> 쓰기 인 시나리오. 여러 reader 가 동시에 읽을 수 있으니 throughput 이 향상.

쓰기가 잦으면 오히려 손해. ReentrantLock 보다 오버헤드가 크고, write lock 대기로 reader 도 같이 멈춘다.

Read 80%, Write 20% 이상 → ReentrantLock 이 더 빠를 가능성
Read 99%, Write 1% → ReentrantReadWriteLock 유리

공정성

ReentrantReadWriteLock fair = new ReentrantReadWriteLock(true);
  • non-fair (기본): writer starvation 가능 (계속 reader 가 들어와 writer 가 기다림)
  • fair: FIFO, writer 기아 방지하지만 throughput 저하

downgrading 과 upgrading

// downgrading (writer → reader), 가능
writeLock.lock();
try {
    data.update();
    readLock.lock();      // ← write 락 유지한 채 read 락도 획득
} finally {
    writeLock.unlock();   // ← write 만 풀어 reader 로 강등
}
try {
    return data.get();
} finally {
    readLock.unlock();
}

// upgrading (reader → writer), 직접 불가능 → deadlock
readLock.lock();
writeLock.lock();    // ❌ deadlock 발생 가능

StampedLock 과의 비교

StampedLock (JDK 1.8) 은 추가로 optimistic read 를 지원. read lock 없이 시도 후 검증. 변경 가능성이 낮을 때 더 빠르다.

항목ReentrantReadWriteLockStampedLock
재진입
조건 변수
optimistic read
인터럽트 응답△ (메서드별)
도입JDK 1.5JDK 1.8

참고

이 글의 용어 (5개)
[Java] CopyOnWriteArrayListjava
정의 는 쓰기 시 배열 전체를 복사 하는 thread-safe 구현. 읽기에는 lock 이 전혀 없고, 쓰기에는 으로 직렬화한다. (JSR-166) 의 컬렉션. 읽기 압도적 다,…
[Java] ReentrantLockjava
정의 는 키워드와 같은 상호 배제 (mutual exclusion) 를 제공하는 클래스 기반 락. JSR-166 (Java 5) 에서 추가됐다. "재진입 (reentrant)" …
[Java] StampedLockjava
정의 는 JDK 1.8 도입의 새 락. 세 가지 모드 제공. 1. Write lock (배타) 2. Read lock (공유) 3. Optimistic read (락 안 잡고 시…
[Java] volatilejava
정의 은 Java 의 키워드. 필드에 붙이면 두 가지를 보장한다. 1. 가시성 (visibility): 한 스레드의 쓰기가 다른 모든 스레드에 즉시 보인다. CPU 캐시에 머무르…
Blocking (블로킹)concurrency
정의 Blocking 은 호출이 결과가 준비될 때까지 호출 스레드를 멈춰두는 실행 방식. 멈춰 있는 동안 그 스레드는 다른 일을 할 수 없다. OS 가 스레드를 sleep 상태로…

이 개념을 다룬 위키 페이지 (1)

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기