Java ReadWriteLock Example
In this example, we are going to demonstrate the use of ReadWriteLock
in Java.
Mutually Exclusive Locks, as the ReentrantLock
discussed in the previous article, offer far less level of concurrency than non-mutually exclusive locks. If multiple threads are accessing an object for reading data, it does not make sense to use a synchronized
block or any other mutually exclusive locks.
The ReadWriteLock
offers two main methods Lock readLock()
and Lock writeLock()
. As the name suggests, the readLock()
method is to acquire read-Lock and writeLock
is called for acquiring the write-Lock.
1. Implementations of ReadWriteLock
ReadWriteLock
is implemented by ReentrantReadWriteLock
Class in java.util.concurrent.locks
package.Multiple Threads can acquire multiple read Locks, but only a single Thread can acquire mutually-exclusive write Lock .Other threads requesting readLocks have to wait till the write Lock is released. A thread is allowed to degrade from write lock to read lock but not vice-versa. Allowing a read thread to upgrade would lead to a deadlock as more than one thread can try to upgrade its lock. The ReentrantReadWriteLock
also supports all the features of the Reentrant lock like providing fair mechanism ,reentrantLocks, Condition
Support (on a write Lock only), allowing interruption on read as well as write Locks.
An example below demonstrating how the ReentrantReadWriteLock
class can be used.
ThreadSafeArrayList.java:
package com.jcg.examples; import java.util.ArrayList; import java.util.List; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; public class ThreadSafeArrayList<E> { private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); private final Lock readLock = readWriteLock.readLock(); private final Lock writeLock = readWriteLock.writeLock(); private final List<E> list = new ArrayList<>(); public void set(E o) { writeLock.lock(); try { list.add(o); System.out.println("Adding element by thread"+Thread.currentThread().getName()); } finally { writeLock.unlock(); } } public E get(int i) { readLock.lock(); try { System.out.println("Printing elements by thread"+Thread.currentThread().getName()); return list.get(i); } finally { readLock.unlock(); } } public static void main(String[] args) { ThreadSafeArrayList<String> threadSafeArrayList = new ThreadSafeArrayList<>(); threadSafeArrayList.set("1"); threadSafeArrayList.set("2"); threadSafeArrayList.set("3"); System.out.println("Printing the First Element : "+threadSafeArrayList.get(1)); } }
OUTPUT :
Adding element by threadmain Adding element by threadmain Adding element by threadmain Printing elements by threadmain Reading from List : 2
2. Closing words
ReadWriteLocks offer greater level of concurrency as compared to traditional mutually-exclusive locks. However, this lock performs best when there are more readLocks required as compared to writeLocks. Using ReadWriteLocks without properly understanding its benefits and trade-offs may hamper the application throughput.
You can download the full source code of this example here : ThreadSafeArrayListExample.zip