Java Programs›Multithreading›Use a ReadWriteLock for a Shared Cache

Use a ReadWriteLock for a Shared Cache in Java

advanced·  Multithreading  ·  Concurrency

Problem

A read-write lock allows any number of readers at the same time but only one writer, and no readers while a write is in progress.

Protect a shared map of prices so that a writer thread and a reader thread can use it at the same time safely.

Input
1 writer (100 updates), 1 reader (1000 reads)
Output
final prices for item0 to item4

Java Program

Java
import java.util.HashMap; import java.util.Map; import java.util.TreeMap; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; public class ReadWriteLockExample { private final Map<String, Integer> prices = new HashMap<>(); private final ReadWriteLock rw = new ReentrantReadWriteLock(); Integer get(String item) { rw.readLock().lock(); // many readers may hold this at once try { return prices.get(item); } finally { rw.readLock().unlock(); } } void put(String item, int price) { rw.writeLock().lock(); // a writer gets exclusive access try { prices.put(item, price); } finally { rw.writeLock().unlock(); } } public static void main(String[] args) throws InterruptedException { ReadWriteLockExample cache = new ReadWriteLockExample(); Thread writer = new Thread(() -> { for (int i = 1; i <= 100; i++) cache.put("item" + (i % 5), i); }); Thread reader = new Thread(() -> { for (int i = 0; i < 1000; i++) cache.get("item1"); }); writer.start(); reader.start(); writer.join(); reader.join(); System.out.println("Final prices: " + new TreeMap<>(cache.prices)); } }

Output

Final prices: {item0=100, item1=96, item2=97, item3=98, item4=99}

Core Logic

Reads take the shared read lock and writes take the exclusive write lock, so frequent reads don't block each other.

How It Works
  1. 1get locks rw.readLock(); several threads may hold it together.
  2. 2put locks rw.writeLock(), which waits until no reader or writer holds the lock.
  3. 3Both unlock in finally blocks.
  4. 4After the threads finish, the map is printed in sorted order.
The writer's last update for item0 is 100, so the final map shows item0=100.
💡

Key Point: Read-write locks help only when reads greatly outnumber writes; otherwise their extra bookkeeping can make them slower than a plain lock.

Key Concepts

ReentrantReadWriteLockreadLock()writeLock()readers-writers

Approach 2: Seeing Shared and Exclusive Access

Java
import java.util.concurrent.locks.ReentrantReadWriteLock; public class ReadWriteLockCounts { public static void main(String[] args) throws InterruptedException { ReentrantReadWriteLock rw = new ReentrantReadWriteLock(); rw.readLock().lock(); Thread secondReader = new Thread(() -> { boolean got = rw.readLock().tryLock(); // readers don't block each other System.out.println("Second reader got the read lock: " + got); if (got) rw.readLock().unlock(); }); secondReader.start(); secondReader.join(); Thread writer = new Thread(() -> { boolean got = rw.writeLock().tryLock(); // a writer must wait for all readers System.out.println("Writer got the write lock while a reader held it: " + got); }); writer.start(); writer.join(); rw.readLock().unlock(); System.out.println("Read locks still held: " + rw.getReadLockCount()); } }

Output

Second reader got the read lock: true Writer got the write lock while a reader held it: false Read locks still held: 0

Core Logic

Trying to acquire each kind of lock while main holds a read lock shows exactly what is shared and what is exclusive.

How It Works
  1. 1A second reader's tryLock() succeeds even though main holds a read lock.
  2. 2A writer's tryLock() fails, because a reader is still active.
  3. 3getReadLockCount() confirms no read locks remain once main unlocks.
The output shows true for the second reader and false for the writer.
💡

Key Point: A thread holding the read lock can't upgrade to the write lock — trying to do so deadlocks; release the read lock first.

Key Concepts

tryLock()getReadLockCount()

Interview Questions

What is the readers-writers problem?

Allowing many simultaneous readers while giving writers exclusive access, without starving either side. A read-write lock is the standard solution.

Is there a faster alternative for mostly-read data?

StampedLock offers optimistic reads that take no lock at all and check afterwards whether a write happened; ConcurrentHashMap is simpler still for map caches.

Learn the Concept

Related Programs