Read-write locks in Java


Series Overview

This article is part of the series. Below are links to all posts in the series:
  1. At-Most-Once Execution
  2. Mastering Read-Write Lock

What's inside this article ⌄
  • Java ReentrantReadWriteLock usage
  • Multiple readers single writer lock
  • StampedLock vs ReadWriteLock Java
  • Read write lock conversion patterns

Another thing that can help you reduce the synchronization overhead is a read-write lock.

Also called MSRW lock (Multiple Readers-Single Writer). It allows:

  • Multiple threads can read a shared resource concurrently.
  • Only one thread can modify (write to) the resource at a time.

When your thread wants to take a read lock and no one is performing a write operation right now, it gets the read lock with ease. Even if there are other readers.

When your thread wants to take a read lock but someone is performing a write operation, you have to wait.

If you want to perform a write operation, you have to wait for any reads to complete.

Let’s have a look at the example:

private ReadWriteLock lock = new ReentrantReadWriteLock();

Reading:

lock.readLock().lock();
try {
    System.out.println("Reading data: " + data);
    return data;
} finally {
    lock.readLock().unlock();
}

Writing:

lock.writeLock().lock();
try {
    System.out.println("Writing data: " + value);
    data = value;
} finally {
    lock.writeLock().unlock();
}

You may ask: What if I have a read lock but suddenly understand that I have to make a write operation?

Can I kind of “convert” a read lock that I already have to write? Like this:

lock.readLock().lock();
try { 
    // ...
    lock.writeLock().lock();
    // ...
finally {
    lock.readLock().unlock();
}

The answer is: not really. The thing is that you may encounter the case when two threads just obtained read locks and now want to obtain a write one. But each thread waits for the other to finish reading. Say hello to deadlock!

However, there is another type of lock named StampedLock. It has a tryConvertToWriteLock() method that you can use to convert a read lock to a write one.

However, it will not succeed in 100% of cases because of the reasons we spoke about above. You can adjust your algorithm accordingly based on whether this method has succeeded.