Executer is a concept evolved from the world of Runnable interface. We have seen that how to create a thread using Runnable interface, extending thread and anonymous classes.
To run the task by implementing Runnable interface, we must have to create the object of the Thread like new thread(RunnableObject).start(). But we know that creating thread have its own overheads and stored in Stack and Heap memory. It’s very expensive to create a thread object just only to run the task in separate thread.
Executors framework (java.util.concurrent.Executor), released by the JAVA 5 in package java.util.concurrent is used to run the Runnable thread objects without creating the Thread object.
The Executor framework is a framework for standardizing invocation, scheduling, execution, and control of asynchronous tasks according to a set of execution policies.
There are three types of implementations provided by the Java:
- ExecutorService
- ThreadPoolExecutor
- Executors (A Class containing factory methods)
To read documentation of Executor framework, refer this URL:
http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Executor.html
It is beyond the scope of article to discuss about all the three implementations of the executor framework provided by the JAVA.
Demo of Using ExecutorService in Threading:
package com.G2.Thread; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; class SomeRunnable implements Runnable { @Override public void run() { for (int i = 0; i < 2; i++) { System.out.println("Counter - " + i + " / Thread Name : " + Thread.currentThread().getName()); } } } public class ExecutorDemo { public static void main(String[] args) { //Create objects of Runnable SomeRunnable obj1 = new SomeRunnable(); SomeRunnable obj2 = new SomeRunnable(); SomeRunnable obj3 = new SomeRunnable(); //Create fixed Thread pool, here pool of 2 thread will created ExecutorService pool = Executors.newFixedThreadPool(2); pool.execute(obj1); pool.execute(obj2); pool.execute(obj3); pool.shutdown(); } }
Output:
Counter – 0 / Thread Name : pool-1-thread-1
Counter – 1 / Thread Name : pool-1-thread-1
Counter – 0 / Thread Name : pool-1-thread-1
Counter – 1 / Thread Name : pool-1-thread-1
Counter – 0 / Thread Name : pool-1-thread-2
Counter – 1 / Thread Name : pool-1-thread-2
If the Threadpool is of size 3, that is if we change the line to :
ExecutorService pool = Executors.newFixedThreadPool(3);
The output would look like:
Counter – 0 / Thread Name : pool-1-thread-1
Counter – 1 / Thread Name : pool-1-thread-1
Counter – 0 / Thread Name : pool-1-thread-3
Counter – 0 / Thread Name : pool-1-thread-2
Counter – 1 / Thread Name : pool-1-thread-2
Counter – 1 / Thread Name : pool-1-thread-3
Callable interface :
There are two disadvantages with using the Runnable interface in JAVA:
- Cannot return value from method run
- Cannot throw Checked Exception
To overcome above problems, java.util.concurrent package has introduced the Callable interface. Instead of run() method, Callable interface defines single call() method, that takes no parameter but can throw exception.
API of Callable interface:
http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Callable.html
Below code demonstrates how to use the callable interface.
package com.G2.Thread; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.FutureTask; class MyCallable implements Callable<Integer> { @Override public Integer call() { // Demonstrates the autoboxing return 111; } } public class CallableDemo { public static void main(String[] args) { FutureTask<Integer> task = new FutureTask<Integer>(new MyCallable()); ExecutorService pool = Executors.newSingleThreadExecutor(); pool.submit(task); try { System.out.println("Value returned from Thread : " + task.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } pool.shutdown(); } }
Output:
Value returned from Thread : 111
FutureTask class implements the interface Future. A Future represents the result of an asynchronous computation. Methods are provided to check if the computation is complete, to wait for its completion, and to retrieve the result of the computation. The result can only be retrieved using method get when the computation has completed, blocking if necessary until it is ready.
To read more on interface Future refer this URL: http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Future.html
Leave a Reply