Java ReentrantReadWriteLock change lock fairness

Introduction

ReentrantLock and ReentrantReadWriteLock classes accepts a boolean parameter named fair in their constructor.

This allows us to control the behavior of both classes.

The false value is the default value and it's called the non-fair mode.

In this mode, JVM will select one job to do the task without any criteria.

The true value is called the fair mode.

In this mode, JVM will select the thread that has been waiting for the most time.

As the tryLock() method doesn't put the thread to sleep, the fair attribute doesn't affect its functionality.


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));
    }//  w  w  w  . j  a va 2  s  .c o m

    // 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(true);
  }

  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