Reader-Writer Lock in Java: Solving the Library Problem in LLD
In Java concurrency and machine coding rounds, synchronizing read-heavy systems with coarse-grained locks is an immediate red flag. The classic "Library Problem"—where thousands browse books while librarians infrequently update the catalog—tests whether you understand lock contention and read-write access asymmetry.
The Mistake Most Candidates Make
- Slapping
synchronizedor a plainReentrantLockacross all operations, serializing every reader and collapsing system throughput to a single thread. - Ignoring writer starvation by defaulting to unfair lock policies where an endless stream of readers completely starves pending writes.
- Omitting proper resource cleanup by failing to place
unlock()insidefinallyblocks, leading to permanent lock leaks when runtime exceptions occur.
The Right Approach
- Core mental model: Multiple readers can safely access shared state concurrently, but a writer demands absolute, exclusive ownership before mutating data.
-
Key entities/classes:
ReadWriteLock,ReentrantReadWriteLock,Lock,CatalogManager. - Why it beats the naive approach: It eliminates reader-on-reader lock contention entirely while maintaining strict consistency boundaries during updates.
Shameless plug: javalld.com has full LLD implementations with step-by-step execution traces — free to use while prepping.
The Key Insight (Code)
public class BookCatalog {
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock(true);
private final Lock readLock = rwLock.readLock(), writeLock = rwLock.writeLock();
private final Map<String, Book> books = new HashMap<>();
public Book get(String id) {
readLock.lock();
try { return books.get(id); }
finally { readLock.unlock(); }
}
public void put(Book book) {
writeLock.lock();
try { books.put(book.id(), book); }
finally { writeLock.unlock(); }
}
}
Key Takeaways
-
ReentrantReadWriteLockmaximizes read-heavy performance by splitting synchronization into shared read locks and exclusive write locks. - Enabling fairness (
fair = true) prevents writer starvation by prioritizing waiting writer threads over newly arriving reader threads in the acquisition queue. - Lock downgrading (acquiring read lock while holding write lock, then releasing write lock) is fully supported, whereas lock upgrading is impossible and triggers deadlocks.
Full working implementation with execution trace available at https://javalld.com/learn/reader-writer
Top comments (0)