Monday, March 23, 2015

Thread pool and executors

In order to prevent overhead of thread creation and reuse existed threads Java supports thread pools since version 1.5. The mechanism of thread pool is based on the equally called pattern. Roughly speaking, thread pool is a queue of initialized threads which makes its usage less expensive neither than using classic single Thread approach.
Java Virtual Machine provides fast access to the queue and every thread has its own instruction to be performed; instructions are customized with objects that implement Callable or Runnable.

Instead of creating threads directly with operations like Thread th = new Thread(); you may use instance of Executor interface.


Executor executor = new Executor() {
    public void execute(Runnable command) {
        command.run();
     }
};
executor.execute(someRunnableInstance);


Executor uses already existed thread and makes the thread to perform operations defined at someRunnableInstance.
ExecutorService (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html) extends Executor interface within new very useful methods. If you’d like to have custom class which implements ExecutorService you must override about 13 methods (jdk 1.8.0.31)
Let’s take a look on a few of them

  •  Future<?> submit(Runnable task), <T> Future<T> submit(Callable<T> task) – submits task to be executed.
  • void shutdown() – initiates the shutdown of the submitted task (no guarantee that the task will be stopped)

The main advantage of ExecutorService is in object which can be returned by “submit” method, this object implements Future interface and represents a result of asynchronous operation (Read more). Method ‘submit’ extends base method execute, the only difference is in returned value.

There are many classes implement ExecutorService interface: ThreadPoolExecutor, ForkJoinPool, FixedthreadPool and more. Choose any depending you task.
Some instances of ExecutorService may be created with Executors factory. Take a look on example.


public static void main(String... args) throws InterruptedException {

 System.out.println("started");
 ScheduledExecutorService service = Executors.newScheduledThreadPool(2);

 service.schedule(new Runnable() {

  public void run() {
   System.out.println("Hey from the pool " + Thread.currentThread().getName());
   
  }
  
 }, 10000, TimeUnit.MILLISECONDS);
 System.out.println("finished");
}

The output of this code will be

started
finished
Hey from the pool pool-1-thread-1

…and we got stuck application
Even when we had left main method block the program didn’t stop its execution because of the scheduled thread. We set timeout 10 seconds since the moment after submit so the thread’s message ‘Hey from the pool pool-1-thread-1’ is printed with a delay. We also didn’t close the executor service correctly, in order to do that service.shutdown() must be invoked. Getting this done we will have the same output but application stops working right after showing the message from the scheduled thread.
NOTE: always check your code for service.shutdown() 

Some more samples around Executors factory
a) ExecutorService service = Executors.newCachedThreadPool();
           // creates a thread pool that creates new threads as needed, but will reuse previously constructed threads when they are available. Threads that have not been used for sixty seconds are terminated and removed from the cache. Thus, a pool that remains idle for long enough will not consume any resources

b) ExecutorService service = Executors.newSingleThreadExecutor();
           // creates an Executor that uses a single worker thread operating off an unbounded queue
          
c) ExecutorService service = Executors.newScheduledThreadPool(10);
           // creates a thread pool that can schedule commands to run after a given delay, or to execute periodically


No comments:

Post a Comment