Pages

Sunday, 22 May 2016

Java ExecutorService Example

In server programming, suppose one client request can be processed using one thread than there will few challenges:

1. It subsequently limit how many client can access server concurrently.
2. In order to support large number of clients, you may decide to use one thread per request paradigm, in which each request is processed by separate Thread, but this require Thread to be created, when request arrived.  Since creation of Thread is time consuming process, it delays request processing.
3. It also limits number of clients based upon how many thread per JVM is allowed, which is obviously a limited number.
Thread pool solves this problem for you, It creates Thread and manage them. Instead of creating Thread and discarding them once task is done, thread-pool reuses threads in form of worker threadSince Thread are usually created and pooled when application starts, your server can immediately start request processing, which can further improve server’s response time.

In short, we need thread pools to better manage threads and decoupling task submission from execution. Thread pool and Executor framework is an excellent thread pool provided by library.

The executor framework separate out task submission from task execution giving us some flexibility in controlling concurrency policy, scheduling etc.

ExecutorService is an interface that extends Executor class and represents an asynchronous execution. It provides us mechanisms to manage the end and detect progress of the asynchronous tasks.

newFixedThreadPool():ExecutorService that creates a thread pool of fixed number of threads.

Methods to start ExecutorService:
execute(Runnable r): Depending on the implementation of the Executor class and may perform the Runnable in a new thread, in a pooled thread, or in the calling thread.

submit(Runnable r): submit() method extends execute(), by returning a Future that represents the submitting task.

Method th close down the ExecutorService:
shutdown():Submitted tasks are executed before the shutting down but new tasks can not be accepted.

shutdownNow():Stops the executing tasks, pause the waiting ones and returns the list of the awaiting ones.

awaitTermination():it can be used in order to wait until all threads are terminated.

package executor;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class WorkerThread implements Runnable {

      private String cmnd;
      CountDownLatch cdl;

      publicWorkerThread(String s,CountDownLatch cdl){
            this.cmnd=s;
            this.cdl = cdl;
      }

      @Override
      public void run() {
            System.out.println(Thread.currentThread().getName()+" start Worker = "+cmnd);
            processCommand();
            System.out.println(Thread.currentThread().getName()+" end Worker = "+cmnd);
            cdl.countDown();
      }

      private void processCommand() {
            try {
                  Thread.sleep(5000);
            } catch(InterruptedException e) {
                  e.printStackTrace();
            }
      }

      @Override
      public String toString(){
            return this.cmnd;
      }
}

public class ExecuterPool {
      public static void main(String[] args) throws InterruptedException {
            ExecutorService executor = Executors.newFixedThreadPool(5);
            CountDownLatch cdl = new CountDownLatch(5);
            for (int i = 0; i < 5; i++) {
                  Runnable worker = new WorkerThread("" + i, cdl);
                  executor.execute(worker);
            }
            executor.shutdown();
            cdl.await();
            System.out.println("Finished all threads");
      }
}

Limitations from traditional Thread overcome by Executor framework (built-in Thread Pool framework).

Poor Resource Management: It keeps on creating new resource for every request. No limit to creating resource. Using Executor framework we can reuse the existing resources and put limit on creating resources.

Not Robust: If we keep on creating new thread we will get StackOverflowException exception consequently our JVM will crash.

Overhead Creation of time: For each request we need to create new resource. To creating new resource is time consuming. i.e. Thread Creating > task.
Using Executor framework we can get built in Thread Pool.

Advantages of Thread Pool:

Use of Thread Pool reduces response time by avoiding thread creation during request or task processing.
Use of Thread Pool allows you to change your execution policy as you need. You can go from single thread to multiple threads by just replacing ExecutorService implementation.

Thread Pool in Java application increases stability of system by creating a configured number of threads decided based on system load and available resource.


Thread Pool frees application developer from thread management stuff and allows focusing on business logic.

No comments:

Post a Comment