Showing posts with label Threads. Show all posts
Showing posts with label Threads. Show all posts

Semaphore in Java

 

Semaphore is an important topic and used under Multi-threading in Java. Semaphore is mainly maintains a set of permits by acquire() and release(). Each acquire() will holds the block if permits are available and it performs the Thread operation and release() the block once it completed the operation. However, no actual permit objects are used; the Semaphore just keeps a count of the number available blocks and acts accordingly. 
We can Semaphore is as same as wait and notify where often used to restrict the number of threads than can access some (physical or logical) resource.
Below are the list of methods and constructors present in Semaphore class. 

Constructors:
There are 2 types of Constructors in Semaphore class 

Semaphore(int permits)

Semaphore(int permits, boolean fair)


Methods:

void acquire()

void acquire(int permits)

void acquireUninterruptibly()

void acquireUninterruptibly(int permits)

int availablePermits()

int drainPermits()

protected Collection<Thread> getQueuedThreads()

int getQueueLength()

boolean hasQueuedThreads()

boolean isFair()

protected void reducePermits(int reduction)

void release()

void release(int permits)

String toString()

boolean tryAcquire()

boolean tryAcquire(int permits)

boolean tryAcquire(int permits, long timeout, TimeUnit unit)

boolean tryAcquire(long timeout, TimeUnit unit)


Now we will simple example for using Semaphore in multi-threading. There are 2 different threads which prints even number by 1 thread and odd numbers by other thread. Numbers should be printed in sequential order like 1,2,3,4,5... etc., using Semaphore class. 



public class SemaphoreTest implements Runnable {
 
 private static int count = 1;
 private boolean flag;
 private static Semaphore even = new Semaphore(0);
 private static Semaphore odd = new Semaphore(1);
 
 public SemaphoreTest(boolean flag){
  this.flag = flag;
 }
 
 private void printEven(){
  while(true){
   try {
    even.acquire();
    System.out.println(Thread.currentThread().getName() + " : "+count++);
    Thread.sleep(100);
    odd.release();
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
 }
 
 private void printOdd(){
  while(true){
   try {
    odd.acquire();
    System.out.println(Thread.currentThread().getName() + "  : "+count++);
    Thread.sleep(100);
    even.release();
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
 }
 
 @Override
 public void run() {  
  if(flag){
   printEven();
  }else{
   printOdd();
  }  
 }
 
 public static void main(String[] args) {
 
  Thread evenThread = new Thread(new SemaphoreTest(true), "EVEN-THREAD");
  Thread oddThread = new Thread(new SemaphoreTest(false), "ODD-THREAD");
  evenThread.start();
  oddThread.start();
 } 
}


OUTPUT:


ODD-THREAD  : 1
EVEN-THREAD : 2
ODD-THREAD  : 3
EVEN-THREAD : 4
ODD-THREAD  : 5
EVEN-THREAD : 6
ODD-THREAD  : 7
EVEN-THREAD : 8
ODD-THREAD  : 9
EVEN-THREAD : 10
ODD-THREAD  : 11
EVEN-THREAD : 12
ODD-THREAD  : 13
EVEN-THREAD : 14
ODD-THREAD  : 15





Java Threads by Extending Thread class and Implementing Runnable Interface

 
Today we will discuss about the Threads in Java. Java Threads are nothing but multiple light weight execution under single process where all Threads will share same resources and runs independently. Most of all operatiing systems will support Threads and each and every Java programs are running atleast with single Thread. For example when Hello World programd starts, JVM creates the Main Thread and calls the program's main() method within same Thread. Also JVM creates other Thread internally to handle Garbage Collection activities. 

       Threads are used to run multiple task simultaneously and asynchronously under a single process. Threads are independent, concurrent paths of execution through a program, and each thread has its own stack own program counter and own local variables. Since each Threads will share same resources, its easy to share information's with each Threads. Just we need to take care on each Thread should not interfere with other threads in the same process.

       Using multi Threads are not easy in complex applications and programmers need to take on multiple Threads based on their business logic's. In Java we can implement Threads in 2 ways. First way by extending Thread class and other way by implementing Runnable interface. In this tutorial lets take a small example and we will discuss about both the ways in separately.


Example for extends Thread Class:



public class MyThreadClass extends Thread{
 
 public MyThreadClass() {}
 
 public MyThreadClass(String tName) {
  this.setName(tName); // Setting Thread name
 }
 
 @Override
 public void run() {
  System.out.println("Thread ::: "+this.getName() +" started");
  processMyThread();
  System.out.println("Thread ::: "+this.getName() +" Completed...");
 }
 
 private void processMyThread(){
  try {
   Thread.sleep(new Random().nextInt(1000));
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
}




public class ExtendThreadExample {
 public static void main(String[] args) {
  MyThreadClass obj1 = new MyThreadClass("Deposit");
  MyThreadClass obj2 = new MyThreadClass("Balance");
  MyThreadClass obj3 = new MyThreadClass("Withdraw");
  obj1.start();
  obj2.start();
  obj3.start();
 }
}




OUTPUT:



Thread ::: Balance started
Thread ::: Withdraw started
Thread ::: Deposit started
Thread ::: Withdraw Completed...
Thread ::: Deposit Completed...
Thread ::: Balance Completed...



       
        In above example we have used extending Thread class and we have Overrided run() method and we have given sample implementation. In 2nd class we have instantiated class for 3 times and we have pass Thread name for our identification.
       

       Once we complete 2nd type (implements Thread) we will discuss about which will be the best practice of using Threads in our application.


Example for implements Runnable interface:




public class MyThreadClass implements Runnable{
 
 public MyThreadClass() {}
 
 public void run() {
  System.out.println("Thread ::: "+Thread.currentThread().getName() +" started");
  processMyThread();
  System.out.println("Thread ::: "+Thread.currentThread().getName() +" Completed...");
 }
 
 private void processMyThread(){
  try {
   Thread.sleep(new Random().nextInt(1000));
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
}




public class ImplementsRunnableExample {
 public static void main(String[] args) {
  MyThreadClass obj = new MyThreadClass1();
  Thread t1 = new Thread(obj,"Deposit");
  Thread t2 = new Thread(obj,"Withdraw");
  Thread t3 = new Thread(obj,"Balance");
  t1.start();
  t2.start();
  t3.start();
 }
}



OUTPUT:



Thread ::: Deposit started
Thread ::: Withdraw started
Thread ::: Balance started
Thread ::: Deposit Completed...
Thread ::: Withdraw Completed...
Thread ::: Balance Completed...
 

Difference between Extending Thread and Implementing Runnable Interface:
 

  • By extending Thread class we are restricted that we can't extend other classes. Whereas while implementing Runnable interface we can extend other class also.
     
  • By extending we are inheriting complete Thread class into our class and we are Overriding only run() method. Whereas while implementing Runnable interface we are having our own implementation for run() method and just using Thread class by instantiating.
     
  • While extending Thread class we need to create multiple instance for our class, whereas in Runnable interface we can single class Object and can be passed to each Thread for its execution.

       Hence we can conclude that implementing Runnable interface will be best and hope you are cleat on the Java Threads. Still there are lot of important methods like wait(), notify(), notifyAll(), join(), yield(), sleep()  which we can discuss in our next tutorial.



 

Creating own ThreadPool using ThreadGruop

 
Welcome to this tutorial. In this tutorial we will discuss about creating our own ThreadPool by limiting no. of threads and pool size. We have 2 class called ThreadPoolTester and MyThreadPool where in ThreadPoolTester we are implementing the run() method and returning the Runabble instance.  Each instance are managed by other class called MyThreadPool which extends the ThreadGroup class. Below are those 2 classes sample code and sample output. 




public class ThreadPoolTester {

 public static void main(String[] args) {
  // Assign your no. of thread to create 
  int noOfProcess = 5; 
  // Assign your own thread pool size
  int poolMaxSize = 2;

  // Creating Threadpool with the thread size given above
  MyThreadPool threadPool = new MyThreadPool(poolMaxSize);
  // Creating threadpool Object
  ThreadPoolTester obj = new ThreadPoolTester();
  long time1 = getTime();

  for (int i = 0; i < noOfProcess; i++) {
   threadPool.process(obj.startProcess(i));
   
   /**
    * Just for showing threadpool not empty we have 
    * place this while loop and making thread to sleep 
    * In realtime while loop should not there, since it
    * will create performance issue. 
    */
   while (threadPool.getTaskListSize() >= poolMaxSize) {
    try {
     System.out.println("Threadpool NOT Empty           - " + threadPool.getTaskListSize());
     Thread.sleep(1000);
     System.out.println("Threadpool size after sleeping - " + threadPool.getTaskListSize());
    } catch (Exception e) {
     e.printStackTrace();
    }
   }
  }
  
  // Finally waiting for all thread to complete its process
  threadPool.join();
  long time2 = getTime();
  System.out.println("Time Taken ::: " + (time2 - time1) +" millisecond(s)");
 }

 private Runnable startProcess(final int taskID) {
  return new Runnable() {
   public void run() {
    System.out.println("Task " + taskID + ": start");
    
    // Putting each task to wait for random milli seconds
    try {
     Thread.sleep(new Random().nextInt(2000));
    } catch (InterruptedException ex) {
    }

    System.out.println("Task " + taskID + ": end");
   }
  };
 }

 public static long getTime() {
  Calendar currentDate = Calendar.getInstance();
  long time = currentDate.getTimeInMillis();
  return time;
 }
}




/**
 * Main ThreadPool class where we are extending ThreadGroup 
 * to implement our own pooling
 */
public class MyThreadPool extends ThreadGroup {
 private boolean active = false;
 private LinkedList<Runnable> qList = null;
 private int tId = 0;
 private static int tPoolID = 0;

 public MyThreadPool(int numThreads) {
  super("Pool - " + (tPoolID++));
  setDaemon(true);
  active = true;
  qList = new LinkedList<Runnable>();
  for (int i = 0; i < numThreads; i++) {
   new PooledThread().start();
   try {
    Thread.sleep(100);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
 }

 public synchronized void process(Runnable task) {
  if (!active) {
   throw new IllegalStateException();
  }
  if (task != null) {
   qList.add(task);
   notify();
  }

 }

 protected synchronized Runnable getTask() throws InterruptedException {
  while (qList.size() == 0) {
   if (!active) {
    return null;
   }
   wait();
  }
  return (Runnable) qList.removeFirst();
 }

 protected int getTaskListSize() {
  return qList.size();
 }

 public synchronized void close() {
  if (active) {
   active = false;
   qList.clear();
   interrupt();
  }
 }

 public void join() {
  synchronized (this) {
   active = false;
   notifyAll();
  }
  Thread[] threads = new Thread[activeCount()];
  int count = enumerate(threads);
  for (int i = 0; i < count; i++) {
   try {
    threads[i].join();
   } catch (InterruptedException ex) {
   }
  }
 }

 private class PooledThread extends Thread {

  public PooledThread() {
   super(MyThreadPool.this, "Task -" + (tId++));
  }

  public void run() {
   while (!isInterrupted()) {
    Runnable process = null;
    try {
     process = getTask();
    } catch (InterruptedException ex) {}
    if (process == null) {
     return;
    }
    try {
     process.run();
    } catch (Throwable t) {
     uncaughtException(this, t);
    }
   }
  }
 }
}



OUTPUT:


Task 0: start
Threadpool NOT Empty           - 2
Task 1: start
Task 1: end
Task 2: start
Task 0: end
Threadpool size after sleeping - 0
Threadpool NOT Empty           - 2
Task 3: start
Task 3: end
Task 4: start
Threadpool size after sleeping - 0
Task 2: end
Task 4: end
Time Taken ::: 3285 millisecond(s)