Read-write locks in Java
Series Overview
This article is part of the series. Below are links to all posts in the series:- 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.