ReentrantReadWriteLock in Java

In this post we’ll see the usage of java.util.concurrent.locks.ReadWriteLock interface and its implementing class ReentrantReadWriteLock in Java with examples.

ReadWriteLock in Java Concurrency

ReadWriteLock as the name itself suggests has a pair of associated locks-

  • One for read-only operations
  • One for writing operations

The usage of read lock and write lock is as follows-

  • The read lock may be held simultaneously by multiple reader threads as long as there are no threads with write lock access.
  • The write lock is exclusive. Which means no thread has acquired either read lock or write lock when the thread obtains a write lock.

Benefits of ReadWriteLock

The traditional way of synchronizing the threads requires a mutually exclusive lock. Even if thread is just reading the shared resource (not modifying it) lock is still mutually exclusive i.e. no other thread can enter the critical section while the resource is locked.
A read-write lock allows for a greater level of concurrency in accessing shared data than that permitted by a mutual exclusion lock.
It works on a principle that while only a single thread at a time (a writer thread) can modify the shared data, in many cases any number of threads can concurrently read the data (hence reader threads) which may help in increasing performance in a multi-threaded environment.

ReentrantReadWriteLock in Java Concurrency

ReentrantReadWriteLock class in Java is an implementing class of the ReadWriteLock interface.

ReentrantReadWriteLock in Java is used in the following way.

To create a ReentrantReadWriteLock-

For getting read lock-

For getting write lock-

Here note that ReadLock and WriteLock are the static nested classes with in the ReentrantReadWriteLock class-

  • ReentrantReadWriteLock.ReadLock– The lock returned by method ReadWriteLock.readLock().
  • ReentrantReadWriteLock.WriteLock– The lock returned by method ReadWriteLock.writeLock().

Locking and unlocking using read lock and write lock is done as follows.
Read lock-

Write Lock-

As you can see ReentrantReadWriteLock follows the same convention as followed with ReentrantLock in Java where call to lock() method is placed before try block and then followed with a try-finally or try-catch-finally block and uses finally block to call unlock() method.

That way unlock() method is called only if the lock is actually acquired and it is also ensured that the unlock() method is called if there is any error after the lock is acquired.

Java ReentrantReadWriteLock constructors

  • ReentrantReadWriteLock()– Creates a new ReentrantReadWriteLock with default (nonfair) ordering properties.
  • ReentrantReadWriteLock(boolean fair)– Creates a new ReentrantReadWriteLock with the given fairness policy.

ReentrantReadWriteLock example in Java

In the example we’ll have a HashMap that is used by multiple threads. While putting element in the HashMap a write lock is acquired as it is a modifying operation. In case of get method a read lock is used so several threads can get values from the HashMap. Then two write threads and three read threads are started to put and get values from the HashMap.

Output

You can see from the output initially two read threads are acquired both can access the locked section. Once read locks are released then only write lock is acquired as write lock has to get exclusive access. There is another read lock that waits for the write lock to release the write lock then only read lock is acquired.

ReentrantReadWriteLock Properties

  1. There is no reader or writer preference ordering for lock access. However, it does support an optional fairness policy.
  2. When ReentrantReadWriteLock is constructed as non-fair, which is the default, the order of entry to the read and write lock is unspecified.
  3. When ReentrantReadWriteLock is constructed as fair, threads contend for entry using an approximately arrival-order policy. When the currently held lock is released, either the longest-waiting single writer thread will be assigned the write lock, or if there is a group of reader threads waiting longer than all waiting writer threads, that group will be assigned the read lock.
  4. Both read and write lock can can reacquire read or write locks in the style of a ReentrantLock. See example here.
  5. Reentrancy also allows downgrading from the write lock to a read lock, by acquiring the write lock, then the read lock and then releasing the write lock.
  6. Upgrading from a read lock to the write lock is not possible.

Reference: https://docs.oracle.com/javase/10/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html

That’s all for the topic ReentrantReadWriteLock in Java. If something is missing or you have something to share about the topic please write a comment.


You may also like

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.