- Callable can return a value, Runnable cannot.
- Callable can throw checked exception, Runnable cannot.
- Only Callable can be used in the following methods of ExecutorService :
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException;<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
throws InterruptedException;<T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException;<T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;(see methods description in the article "Concurrency in java. ExecutorService.")
Other differences:
- Callable interface declares
V call() throws Exception;method to create task, Runnable interface -run();
- Class Thread supports Runnable only, but it is possible to run Callable task using method of ExecutorService:
<T> Future<T> submit(Callable<T> task);Other classes from java.util.concurrent package have API that works with
Callable. For example, Executors class provides number of methods to get Callable object or to convert Runnable to Callable.Example of Callable interface usage:
[code language="java" gutter="true" tabsize="4"]
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.Callable;
public class CallableTask implements Callable {
private String data;
public CallableTask (String data) {
this.data = data;
}
@Override
public String call() throws Exception {
DateFormat formatter = SimpleDateFormat.getTimeInstance();
//prints thread name, time and data
System.out.println(Thread.currentThread().getName() + " started processing at " +
formatter.format(new Date()) + " : " + data);
try {
//sleep 5 seconds
Thread.sleep(5000);
} catch (InterruptedException e) {
//some exception handler
}
//some business exception
if(data.equals("Data3"))
throw new Exception();
return Thread.currentThread().getName() + " finished processing of " + data;
}
}
[/code]
[code language="java" gutter="true" tabsize="4"]
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
public class DataProcessor {
private static final int THREAD_NUMBER = 3;
private static final int WAITING_TIMEOUT_IN_DAYS = 1;
public void processData(List someData) throws InterruptedException {
//creates pool of 3 thread
ThreadPoolExecutor threadPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(THREAD_NUMBER);
for (String data : someData) {
//submits task that should be executed
Future task = threadPool.submit(new CallableTask(data));
//don't forget to process exception
try {
//print result that return our call() method
System.out.println(task.get());
} catch (ExecutionException e) {
System.out.println("Exception was thrown by CallableTask");
}
}
//shutdown to reclaim resources (threads in the pool will exist until shutdown)
threadPool.shutdown();
try {
//blocks shutdown untill submitted tasks complete execution
threadPool.awaitTermination(WAITING_TIMEOUT_IN_DAYS, TimeUnit.DAYS);
} catch (InterruptedException e) {
//some exception handler
}
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
//list with data for test
List data = new ArrayList();
for (int i = 1; i < 6; i++) {
data.add("Data" + i);
}
//data processing
DataProcessor dataProcessor = new DataProcessor();
dataProcessor.processData(data);
}
}[/code]
Result:
No comments:
Post a Comment