Java ReentrantLock 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.Lock;
import java.util.concurrent.locks.ReentrantLock;

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

    Thread thread[] = new Thread[10];
    for (int i = 0; i < 10; i++) {
      thread[i] = new Thread(new Job(shared), "Thread " + i);
    }//w  w  w  .j a  va2  s  .  com

    // Launch a thread ever 0.1 seconds
    for (int i = 0; i < 10; i++) {
      thread[i].start();
      try {
        Thread.sleep(100);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }

}

class Job implements Runnable {
  private SharedResource shared;

  public Job(SharedResource printQueue) {
    this.shared = printQueue;
  }

  @Override
  public void run() {
    System.out.printf("%s: Going to do a job\n", Thread.currentThread().getName());
    shared.printJob(new Object());
    System.out.printf("%s: The document has been done\n", Thread.currentThread().getName());
  }

}

class SharedResource {
  private final Lock queueLock = new ReentrantLock(false);

  public void printJob(Object document) {
    queueLock.lock();

    try {
      Long duration = (long) (Math.random() * 10000);
      System.out.printf("%s: Queue: doing a Job during %d seconds\n", Thread.currentThread().getName(),
          (duration / 1000));
      Thread.sleep(duration);
    } catch (InterruptedException e) {
      e.printStackTrace();
    } finally {
      queueLock.unlock();
    }

    queueLock.lock();
    try {
      Long duration = (long) (Math.random() * 10000);
      System.out.printf("%s: PrintQueue: Printing a Job during %d seconds\n", Thread.currentThread().getName(),
          (duration / 1000));
      Thread.sleep(duration);
    } catch (InterruptedException e) {
      e.printStackTrace();
    } finally {
      queueLock.unlock();
    }
  }
}



PreviousNext

Related