Runnable vs Callable

Runnable Callable- Introduced in Java 1.5
Definition public interface Runnable {
public abstract void run();
}
To use Runnable, we need to override the run() method
public interface Callable {
V call() throws Exception;
}
To use Callable, we need to override the call() method
Returns Value? NO
YES
Can Throw Checked Exception? NO YES
When to use If you have a fire and forget task then use Runnable. If you are trying to retrieve a value from a task, then use Callable.
Can we pass it in a Thread? YES. NO

There is no constructor defined in the Thread class which accepts a Callable type.So in order to execute a Callable instance you need to use the ExecutorService interface of Java 5 Executor framework.Submitting a callable to ExecutorService returns Future Object which represents the lifecycle of a task and provides methods to check if the task has been completed or cancelled, retrieve the results and cancel the task.

Moreover, both Runnable and Callable are supported by the Executor framework.

Examples

Runnable

package com.blog;

public class TestRunnable {

public static void main(String[] args) {
for(int i=0; i <=10; i++){
final int counter =i;
Runnable runnable = new Runnable(){
@Override
public void run() {
System.out.println(counter*100);
}

};
Thread thread = new Thread(runnable);
thread.start();
}
}

}

Output
0
300
200
100
500
400
600
700
800
900
1000

Callable

package com.blog;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class TestCallable {

public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executor = Executors.newFixedThreadPool(10);//Creates a thread pool that reuses 10 threads
List futures = new ArrayList<>();
for(int i=0; i <=10; i++){
final int counter =i;
Callable callable = new Callable(){
@Override
public Integer call() {
return counter*100;
}

};
Future future =executor.submit(callable);// returns Future Object which represents the lifecycle of a task and provides methods to check
//if the task has been completed or cancelled, retrieve the results and cancel the task.
futures.add(future);
}
for(Future future : futures){
System.out.println(future.get());//get() method of Future object returns the result of call() method of Callable object.
}
}

}

Output
0
100
200
300
400
500
600
700
800
900
1000

Future

Let us look into the important APIs of Future:

1.  boolean cancel(boolean mayInterruptIfRunning)

Attempts to cancel execution of this task. This attempt will fail if the task has already completed, has already been cancelled, or could not be cancelled for some other reason. If successful, and this task has not started when cancel is called, this task should never run. If the task has already started, then the mayInterruptIfRunning parameter determines whether the thread executing this task should be interrupted in an attempt to stop the task.
After this method returns, subsequent calls to isDone() will always return true. Subsequent calls to isCancelled() will always return true if this method returned true.

Parameters:
mayInterruptIfRunning – true if the thread executing this task should be interrupted; otherwise, in-progress tasks are allowed to complete

Returns:
false if the task could not be cancelled, typically because it has already completed normally; true otherwise

2. boolean isCancelled()
Returns true if this task was cancelled before it completed normally.

3. boolean isDone()
Returns true if this task completed. Completion may be due to normal termination, an exception, or cancellation — in all of these cases, this method will return true.

4. V get() throws InterruptedException,ExecutionException
Waits if necessary for the computation to complete, and then retrieves its result.

Returns:the computed result

Throws:
CancellationException – if the computation was cancelled
ExecutionException – if the computation threw an exception
InterruptedException – if the current thread was interrupted while waiting

5. V get(long timeout,TimeUnit unit) throws InterruptedException,ExecutionException,TimeoutException
Waits if necessary for at most the given time for the computation to complete, and then retrieves its result, if available.
Parameters:
timeout – the maximum time to wait
unit – the time unit of the timeout argument
Returns:the computed result
Throws:
CancellationException – if the computation was cancelled
ExecutionException – if the computation threw an exception
InterruptedException – if the current thread was interrupted while waiting
TimeoutException – if the wait timed out

Leave a Reply

Your email address will not be published. Required fields are marked *