Java ReentrantReadWriteLock synchronize data access with read/write locks

Introduction

The ReadWriteLock interface and ReentrantReadWriteLock class has two locks.

One is for read operations and another one is for write operations.

There can be more than one thread using read operations simultaneously, but only one thread can be using write operations.

When a thread is doing a write operation, there can't be any thread doing read operations.

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

public class Main {
  public static void main(String[] args) {
    SharedResource shared = new SharedResource();

    Thread threadsReader[] = new Thread[5];

    // Creates five readers and threads to run them
    for (int i = 0; i < 5; i++) {
      threadsReader[i] = new Thread(new Reader(shared));
    }/*from w w w. ja  va  2s  .c om*/

    // Creates a writer and a thread to run it
    Thread threadWriter = new Thread(new Writer(shared));

    // Starts the threads
    for (int i = 0; i < 5; i++) {
      threadsReader[i].start();
    }
    threadWriter.start();
  }
}

class SharedResource {
  private double v1;
  private double v2;

  private ReadWriteLock lock;

  public SharedResource() {
    v1 = 1.0;
    v2 = 2.0;
    lock = new ReentrantReadWriteLock();
  }

  public double getV1() {
    lock.readLock().lock();
    double value = v1;
    lock.readLock().unlock();
    return value;
  }

  public double getV2() {
    lock.readLock().lock();
    double value = v2;
    lock.readLock().unlock();
    return value;
  }

  public void setPrices(double price1, double price2) {
    lock.writeLock().lock();
    this.v1 = price1;
    this.v2 = price2;
    lock.writeLock().unlock();
  }
}

class Reader implements Runnable {
  private SharedResource shared;

  public Reader(SharedResource pricesInfo) {
    this.shared = pricesInfo;
  }

  @Override
  public void run() {
    for (int i = 0; i < 10; i++) {
      System.out.printf("%s: V1: %f\n", Thread.currentThread().getName(), shared.getV1());
      System.out.printf("%s: V2: %f\n", Thread.currentThread().getName(), shared.getV2());
    }
  }

}

class Writer implements Runnable {
  private SharedResource shared;

  public Writer(SharedResource s) {
    this.shared = s;
  }

  @Override
  public void run() {
    for (int i = 0; i < 3; i++) {
      System.out.printf("Writer: Attempt to modify the prices.\n");
      shared.setPrices(Math.random() * 10, Math.random() * 8);
      System.out.printf("Writer: Prices have been modified.\n");
      try {
        Thread.sleep(2);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }

}



PreviousNext

Related