Semaphores in Java

Spread the love

Semaphore is a construct in java thread model in which threads sends signals to each other. Semahores are implemented to avoid missed signals.

The traditional way for a thread to send signals to other thread is using wait and notify methods. But semaphores are much more efficient and reliable than wait/notify. We will discuss below.

Java 5 comes with a built-in Semaphore so you don’t have to implement your own and it is part of the java.util.concurrenct.Semaphore package.

public class Semaphore {
  private boolean semSignal = false;

  public synchronized void take() {
    this.semSignal = true;
    this.notify();
  }

  public synchronized void release() throws InterruptedException{
    while(!this.semSignal) wait();
    this.semSignal = false;
  }

}

If you see the release method, it checks the semSignal value if it is true. If it is false, then it waits.

Now if you see the take method, it sets the value as true and notifies others.

Now the thread which called the release method, gets notified and sets the value as false.Internally if you see, wait and notify are used.

Now consider we didn’t have semaphore and used only wait and notify.

If a thread called notify first and then another thread called wait, then the 2nd thread would go into waiting state forever. Scary right!!!

But if we used semaphore and called take first and then release, then we would not be in the same situation because we are internally using a semSignal variable to call wait. If take was called first, the value of the semSignal variable would be set to to true and the subsequent call to release method would not result in a wait state for the thread.

Now let’s implement the full example.

public class SemaphoreMain
{
  public static void main(String args[])
   {
      Semaphore sem = new Semaphore();

      SenderThread st = new SenderThread(sem);

      ReceiverThread rt = new ReceiverThread(sem);

      rt.start();
      st.start();
   }
}

public class SenderThread {
  Semaphore semaphore = null;

  public SenderThread(Semaphore semaphore){
    this.semaphore = semaphore;
  }

  public void run(){
    while(true){
      //execute something and then send the signal
      this.semaphore.take();

    }
  }
}

public class ReceiverThread {
  Semaphore semaphore = null;

  public ReceiverThread(Semaphore semaphore){
    this.semaphore = semaphore;
  }

  public void run(){
    while(true){
      this.semaphore.release();
      //receive signal and execute further
    }
  }
}