Read/Write Locks

In Java, read and write locks are mechanisms used to manage access to shared resources by multiple threads. They are provided by the java.util.concurrent.locks package and are designed to improve concurrency by allowing multiple threads to read data simultaneously while ensuring exclusive access for writing.

Read Lock (Shared Lock):

A read lock allows multiple threads to read a shared resource concurrently, but it prevents any thread from acquiring a write lock as long as there is at least one active read lock. This means that threads holding the read lock can read the data concurrently without interfering with each other.

To use a read lock in Java, you typically create an instance of ReentrantReadWriteLock and acquire the read lock using its readLock() method: 

import java.util.concurrent.locks.ReentrantReadWriteLock;
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
ReentrantReadWriteLock.ReadLock readLock = lock.readLock();
// Acquiring the read lock
readLock.lock();
try {
    // Read from the shared resource
} finally {
    // Release the read lock
    readLock.unlock();
}Code language: JavaScript (javascript)

Write Lock (Exclusive Lock):

A write lock allows exclusive access to a shared resource. When a thread acquires a write lock, it prevents any other thread (whether for reading or writing) from accessing the resource until the write lock is released. This ensures that no other thread can modify the resource while it is being written to, maintaining data consistency.

To use a write lock in Java, you create an instance of ReentrantReadWriteLock and acquire the write lock using its writeLock() method:

import java.util.concurrent.locks.ReentrantReadWriteLock;
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
// Acquiring the write lock
writeLock.lock();
try {
    // Write to the shared resource
} finally {
    // Release the write lock
    writeLock.unlock();
}Code language: JavaScript (javascript)

When to Use Read vs Write Locks:

  • Read Locks: Use read locks when the shared resource is read frequently but updated infrequently. Multiple threads can read simultaneously, which can significantly improve performance in scenarios where reading is the predominant operation.
  • Write Locks: Use write locks when the shared resource needs to be updated. Write locks ensure that only one thread can modify the resource at a time, preventing race conditions and maintaining

Program

This demonstrates the use of ReentrantReadWriteLock to coordinate read and write access to a shared resource. The program should simulate multiple threads attempting to read from and write to a common integer variable using separate read and write locks. Readers (like Mahesh and Chinmayi) should be allowed to read simultaneously if no writing is occurring, while the writer (Paani) should gain exclusive access to update the shared resource.

//ReadWriteLockDemo.java
import java.util.concurrent.locks.*;
public class ReadWriteLockDemo {
    private static ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    private static ReentrantReadWriteLock.ReadLock readLock = lock.readLock();
    private static ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
    private static int sharedResource = 0;
   
   public static void readFromResource() {
        readLock.lock();
        try {
            System.out.println("Reader " + Thread.currentThread().getName() + " is reading: " + sharedResource);
            Thread.sleep(100); // Simulate reading time
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            readLock.unlock();
        }
    }
    
	public static void writeToResource() {
        writeLock.lock();
        try {
            System.out.println("Writer " + Thread.currentThread().getName() + " is writing...");
            sharedResource++;
            System.out.println("Writer updated the resource to: " + sharedResource);
            Thread.sleep(200); // Simulate writing time
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            writeLock.unlock();
        }
	}
	public static void main(String[] args) throws InterruptedException {
        // Start Mahesh reader thread
        Thread reader1 = new Thread(ReadWriteLockDemo::readFromResource);
        reader1.setName("Mahesh");
        // Start Chinmayi reader thread
        Thread reader2 = new Thread(ReadWriteLockDemo::readFromResource);
        reader2.setName("Chinmayi");
        // Start Paani writer thread
        Thread writer = new Thread(ReadWriteLockDemo::writeToResource);
        writer.setName("Paani");
        reader1.start();
        reader2.start();
        writer.start();
        reader1.join();
        reader2.join();
        writer.join();
    }
}

/*

C:\06>javac ReadWriteLockDemo.java
C:\>java ReadWriteLockDemo
Writer Paani is writing...
Writer updated the resource to: 1
Reader Chinmayi is reading: 1
Reader Mahesh is reading: 1

C:\>java ReadWriteLockDemo
Reader Chinmayi is reading: 0
Reader Mahesh is reading: 0
Writer Paani is writing...
Writer updated the resource to: 1

*/

 Read and write locks in Java provide a flexible mechanism for managing concurrent access to shared resources. By carefully choosing between read and write locks based on the nature of data access patterns, you can optimize performance and ensure thread safety in multi-threaded applications.

Scroll to Top