Thursday, June 19, 2014

Implementing Counting Semaphore Using Lock

Lock and Semphore is both a synchronization mechanism for multi-threaded environment. Both Lock and Semphore can be created by using each other. Lock can implemented using semaphore and semaphore can be implemented using Lock.

In this post, I have implemented a counting semaphore using Lock in java. A class Semphore is defined with instance member as Lock, Condition and integer. The Lock has been used to make the Semaphore class thread safe, and Condition variable is used as communication tool between the release() and acquire() method , and the integer variable permit is used to track, the no of permits as given to semaphore.

The acquire() method of the Semaphore has been implemented in such a way that, only for the allowed no of permits, thread is allowed to proceed, otherwise it will wait until the condition remain true i.e semaphore has been released by some other or same thread.

The release() method, simply acquire() the lock and then check for the permits count, if the permits count is greater than zero, means number of permits has already been granted to thread, hence it is safe for release(), i.e to increment the permit count and signal to waiting threads who are waiting for the semaphore permits using acquire() method, so that further thread can get permit using semaphore to proceed further.

package read.java.thread.semaphore;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


class Semaphore{
 
 int permits;
 Lock lock=new ReentrantLock();
 Condition condition=lock.newCondition();
 
 public Semaphore(int permits){
  this.permits=permits;
 }
 
 
 public void release() throws Exception{
  try{
   lock.lock();
   if(permits >= 0){
    permits++;
    System.out.println("Semaphore Released Notified to Others" + permits);
    condition.signalAll();
   }
  }catch(Exception exp){
   exp.printStackTrace();
   throw exp;
  }finally{
   lock.unlock();
   System.out.println("Semaphore Released Permit Count ===" + permits);
  }
 }
 
 
 public void acquire() throws InterruptedException{
  try{
   lock.lock();
   while(permits <= 0){
    System.out.println("Waiting for semaphore to obtain Permits =======" + permits);
    condition.await();
   }
   permits--;
  }catch(InterruptedException exp){
   throw exp;
  }
  finally{
   lock.unlock();
   System.out.println("Semaphore Acquired Permit Count ===" + permits);
  }
 } 
}




public class CountingSemaphoreUsingLock {

 
 public static void main(String[] args) throws Exception{
  Semaphore sem=new Semaphore(4);
  for(int i=0; i < 5 ; i++){
   sem.acquire();
  }
 }

}


No comments:

Post a Comment