ReadWriteLock — 읽기/쓰기 락
ReadWriteLock — 읽기/쓰기 락
ReadWriteLock은 읽기 전용 연산용 락과 쓰기용 락 한 쌍을 유지하는 락이에요. 읽기 락은 작가(writer)가 없는 동안 여러 독자(reader) 스레드가 동시에 보유할 수 있고, 쓰기 락은 독점적이에요.
본문
개념 이해하기
ReadWriteLock은 읽기 전용 연산용 락과 쓰기용 락 한 쌍을 유지해요. 읽기 락은 작가가 없는 동안 여러 독자가 동시에 보유할 수 있고, 쓰기 락은 독점이에요.
public interface ReadWriteLock
모든 구현은 writeLock 연산의 메모리 동기화 효과(Lock 인터페이스에 명시)가 연관 readLock에도 적용되도록 보장해야 해요. 즉, 읽기 락을 성공적으로 획득한 스레드는 쓰기 락의 이전 해제 시 이루어진 모든 업데이트를 보게 돼요.
읽기-쓰기 락은 상호 배제 락보다 더 높은 수준의 동시성을 허용해요. 단일 스레드만 공유 데이터를 수정할 수 있지만, 많은 경우 임의 개수의 스레드가 동시에 데이터를 읽을 수 있다는 사실을 활용해요.
성능 고려 사항
실제로 이 동시성 증가는 다중 프로세서에서, 그리고 공유 데이터의 접근 패턴이 적합할 때만 완전히 실현돼요. 읽기-쓰기 락이 상호 배제 락보다 성능을 개선할지는 다음에 달려 있어요:
- 데이터가 읽히는 빈도 vs 수정되는 빈도
- 읽기·쓰기 연산의 지속 시간
- 데이터에 대한 경합(동시에 읽거나 쓰려는 스레드 수)
예를 들어 처음 데이터로 채워진 뒤 자주 수정되지 않고 빈번히 검색되는 컬렉션(예: 어떤 종류의 디렉토리)은 이상적인 후보예요. 그러나 업데이트가 잦아지면 데이터가 대부분 독점 락 상태로 지내 동시성 증가가 거의 없어요. 또한 읽기 연산이 너무 짧으면 구현 오버헤드가 실행 비용을 지배할 수 있어요. 결국 프로파일링과 측정이 판단을 내려요.
정책 결정
구현이 해야 할 여러 정책 결정이 있어요:
- 작가가 쓰기 락을 해제할 때 독자와 작가가 모두 기다릴 경우 읽기 락과 쓰기 락 중 무엇을 부여할지. 작가 선호가 흔해요(쓰기는 짧고 드물 것이 기대되므로).
- 독자가 활성이고 작가가 대기 중일 때 독자를 렌더하는지 — 독자 선호는 작가를 무기한 지연시킬 수 있어요.
- 락이 재진입(reentrant) 적인지 — 쓰기 락 보유자가 재획득할 수 있는지, 쓰기 락을 보유하면서 읽기 락을 얻을 수 있는지.
- 쓰기 락이 개입하는 작가 없이 읽기 락으로 다운그레이드될 수 있는지, 읽기 락이 쓰기 락으로 업그레이드될 수 있는지.
메서드
Lock readLock() — 읽기에 쓰는 락을 반환해요.
Lock writeLock() — 쓰기에 쓰는 락을 반환해요.
대표 구현체는 ReentrantReadWriteLock이에요.