Wednesday 3 May 2017

ExecutorService


Executors framework (java.util.concurrent.Executor), released with the JDK 5 in package java.util.concurrent is used to run the Runnable objects without creating new threads every time and mostly re-using the already created threads. An ExecutorService is thus very similar to a thread pool. In fact, the implementation of ExecutorService presents in the java.util.concurrent package is a thread pool implementation.
                                            
Executor Service Hierarchy
 
The Executor framework helps to decouple a command submission from command execution. 
In the java.util.concurrent package there are three interfaces:
Executor — It is used to submit a new task.

ExecutorService — A sub-interface of Executor that adds methods to manage life cycle of threads used to run the submitted tasks and methods to produce a Future to get a result from an asynchronous computation.

ScheduledExecutorService — A sub-interface of ExecutorService, to execute commands periodically or after a given delay.

Executor Interface


This Interface used to submit a new task. Executor is an interface that declares only one method.
/**Executes the given command at some time in the future. The command may execute in a new thread, in a pooled thread, or in the calling thread, at the discretion of the Executor implementation.

Parameters:
command the runnable task
Throws:
RejectedExecutionException - if this task cannot be accepted for execution
NullPointerException - if command is null**/

void java.util.concurrent.Executor.execute(Runnable command)


ExecutorService Interface


A sub-interface of Executor that adds methods to manage the lifecycle of threads used to run the submitted tasks and methods to produce a Future to get a result from an asynchronous computation.

ExecutorService adds a more useful and advanced version method to execute commands, submit.

Passing a Callable to the submit method is possible to get a Future object and use it to retrieve the result of the asynchronous computation.

Additionally, it is possible to shutdown an ExecutorService rejecting submission of new commands. Using the shutdown method all submitted commands will be executed before stopping the ExecutorService, but no new command is accepted. A call to shutdownNow prevents waiting for tasks to be executed and try to stop all currently executing commands.

Since ExecutorService is an interface, you need to its implementations in order to make any use of it. The ExecutorService has the following implementation in the java.util.concurrent package:

ThreadPoolExecutor
ScheduledThreadPoolExecutor

Creating an ExecutorService
How you create an ExecutorService depends on the implementation you use. However, you can use the Executors factory class to create ExecutorService instances too.

ExecutorService executorService1 = Executors.newSingleThreadExecutor();

ExecutorService executorService2 = Executors.newFixedThreadPool(10);

ExecutorService executorService3 = Executors.newScheduledThreadPool(10);

ExecutorService Usage
There are a few different ways to delegate tasks for execution to an ExecutorService:
execute(Runnable)
submit(Runnable)
submit(Callable)
invokeAny(...)
invokeAll(...)

execute(Runnable)
The execute(Runnable) method takes a java.lang.Runnable object, and executes it asynchronously.
ExecutorService executorService = Executors.newSingleThreadExecutor();

executorService.execute(new Runnable() {
     public void run() {
           System.out.println("Asynchronous task");
     }
});
executorService.shutdown();

There is no way of obtaining the result of the executed Runnable.

submit(Runnable)
The submit(Runnable) method also takes a Runnable implementation but returns a Future object. This Future object can be used to check if the Runnable as finished executing. 
Future future = executorService.submit(new Runnable() {
           public void run() {
                System.out.println("Asynchronous task");
           }
     });
future.get();//returns null if the task has finished correctly.

submit(Callable)
The submit(Callable) method is similar to the submit(Runnable) method except for the type of parameter it takes. The Callable instance is very similar to a Runnable except that its call() method can return a result. The Runnable.run() method cannot return a result.

The Callable's result can be obtained via the Future object returned by the submit(Callable) method.

Future future = executorService.submit(new Callable(){
           public Object call() throws Exception {
                System.out.println("submit Callable");
                return "Callable Result";
           }
     });

System.out.println("future.get() = " + future.get());

The above code example will output this:
     submit Callable
     future.get() = Callable Result

ExecutorService Shutdown
When you are done using the ExecutorService you should shut it down, so the threads do not keep running.

shutdown()
To terminate the threads inside the ExecutorService you call its shutdown() method. The ExecutorService will not shut down immediately, but it will no longer accept new tasks, and once all threads have finished current tasks, the ExecutorService shuts down. All tasks submitted to the ExecutorService before shutdown() is called, are executed.

shutdownNow()
If you want to shut down the ExecutorService immediately, you can call the shutdownNow() method. This will attempt to stop all executing tasks right away and skips all submitted but non-processed tasks. There are no guarantees given the executing tasks. Perhaps they stop, perhaps execute until the end. It is a best effort attempt.

ScheduledExecutorService Interface
A sub-interface of ExecutorService which can be used to execute commands periodically or after a given delay.

The ScheduledExecutorService is used to schedule command executions after a given delay or periodically, it must be used as a replacement for Timer and TimerTask.

It uses the method schedule to run the command after a given delay of time, scheduleAtFixedRate and scheduleWithFixedDelay are used to execute a task periodically.

ScheduledExecutorService schExServ = Executors.newScheduledThreadPool(5);

ScheduledFuture scheduledFuture = schExServ.schedule(new Callable() {
      public Object call() throws Exception {
            System.out.println("Executed!");
            return "Called!";
      }
}, 5, TimeUnit.SECONDS);

ScheduledExecutorService Methods
schedule (Callable task, long delay, TimeUnit timeunit)
schedule (Runnable task, long delay, TimeUnit timeunit)
scheduleAtFixedRate (Runnable, long initialDelay, long period, TimeUnit timeunit)
scheduleWithFixedDelay (Runnable, long initialDelay, long period, TimeUnit timeunit)

No comments:

Post a Comment

Related Posts Plugin for WordPress, Blogger...