Java - Read and Write Lock

Introduction

A ReentrantLock provides a mutually exclusive locking mechanism.

Only one thread can own the ReentrantLock at a time.

If you have a data guarded by a ReentrantLock, a writer thread as well as a reader thread must acquire the lock one at a time to modify or to read the data.

This restriction may downgrade the performance if data is read frequently and modified infrequently.

If the data is being modified, only one writer thread should have the access to the data structure.

Read-Write lock

Read-Write lock implements this kind of locking mechanism using an instance of the ReadWriteLock interface.

ReadWriteLock has two methods: one to get the reader lock and another to get the writer lock.

public interface ReadWriteLock {
 Lock readLock();
 Lock writeLock();
}

ReentrantReadWriteLock class is an implementation of the ReadWriteLock Interface.

Only one thread can hold the write lock of ReentrantReadWriteLock, whereas multiple threads can hold its read lock.

The following code demonstrates ReentrantReadWriteLock.

Demo

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class Main {

  static ReadMostlyData data  = new ReadMostlyData(10);
  public static void main(String[] argv) {
    //from  ww w.ja  va 2 s.c o  m
    // Create two Thread objects
    Thread t1 = new Thread(Main::print);
    Thread t2 = new Thread(Main::print);

    // Start both threads
    t1.start();
    t2.start();
  }

  public static void print() {
    for (int i = 1; i <= 5; i++) {
      data.setValue(i);
      try {
        Thread.sleep(1000);
      } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
      System.out.println("data:"+data.getValue());
    }
  }
}

class ReadMostlyData {
  private int value;
  private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
  private Lock rLock = rwLock.readLock();
  private Lock wLock = rwLock.writeLock();

  public ReadMostlyData(int value) {
    this.value = value;
  }

  public int getValue() {
    // Use the read lock, so multiple threads may read concurrently
    rLock.lock();
    try {
      return this.value;
    } finally {
      rLock.unlock();
    }
  }

  public void setValue(int value) {
    // Use the write lock, so only one thread can write at a time
    wLock.lock();
    try {
      this.value = value;
    } finally {
      wLock.unlock();
    }
  }
}

Result

Related Topic