Java Semaphore control concurrent access to a resource

Introduction

The following code shows how to use the semaphore mechanism provided by the Java language.

A semaphore is a counter that protects the access to one or more shared resources.

To access the shared resources, the thread must acquire the semaphore.

If the internal counter of the semaphore is greater than 0, the semaphore decrements the counter.

And JVM allows access to the shared resource.

If the counter of the semaphore is 0, the semaphore puts the thread to sleep until the counter is greater than 0.

A value of 0 in the counter means all the shared resources are used by other threads.

Fairness in semaphores

The default mode in Semaphore is called the non-fair mode.

In this mode, when the synchronization resource is released, one of the waiting threads is selected to get this resource.

In the fair mode JVM will select the thread that has been waiting for more time.

You can set the fair mode in the constructor of Semaphore class.


import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class Main {
  public static void main(String args[]) {
    SharedResource printQueue = new SharedResource();
    Thread thread[] = new Thread[10];
    for (int i = 0; i < 10; i++) {
      thread[i] = new Thread(new Job(printQueue), "Thread " + i);
      thread[i].start();/*from  w  ww .ja  v  a  2 s .c  om*/
    }
  }
}

class Job implements Runnable {
  private SharedResource printQueue;

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

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

class SharedResource {

  private final Semaphore semaphore = new Semaphore(1);

  public void printJob(Object document) {
    try {
      semaphore.acquire();
      Long duration = (long) (Math.random() * 10);
      System.out.println(Thread.currentThread().getName()+" waited "+ duration);
      Thread.sleep(duration);
      TimeUnit.SECONDS.sleep(duration);
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      semaphore.release();
    }
  }

}



PreviousNext

Related