The
Here is a diagram illustrating a thread delegating a task to an
Here is a
The
The above code example will output this:
If one of the tasks complete (or throws an exception), the rest of the
Here is a code example:
This code example will print out the object returned by one of the
Keep in mind that a task might finish due to an exception, so it may not have "succeeded". There is no way on a
Here is a code example:
java.util.concurrent.ExecutorServiceExample interface represents an asynchronous execution mechanism which is capable of executing tasks in the background. An ExecutorService is thus very similar to a thread pool. In fact, the two implementations of ExecutorService present in the java.util.concurrent package are themselves thread pool implementations. Here is a diagram illustrating a thread delegating a task to an
ExecutorService for asynchronous execution: ![]() |
| A thread delegating a task to an ExecutorService for asynchronous execution. |
ExecutorService Implementations
SinceExecutorService is an interface, you need to use one of its implementations in order to use it. The ExecutorService has the following implementation in the java.util.concurrent package: Creating an ExecutorService
How you create anExecutorService depends on the implementation you use. However, you can use the Executors factory class to create ExecutorService instances too. Here are a few examples: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 anExecutorService: - execute(Runnable)
- submit(Runnable)
- submit(Callable)
- invokeAny(...)
- invokeAll(...)
execute(Runnable)
Theexecute(Runnable) method takes a java.lang.Runnable object, and executes it asynchronously. Here is an example. 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 task, if necessary. You will have to use a Callable for that (explained in the following sections). submit(Runnable)
Thesubmit(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. Here is a
submit() example:Future future = executorService.submit(new Runnable()
{
public void run(){
System.out.println("Asynchronous task");
}
});submit(Callable)
Thesubmit(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. Here is a code example:Future future = executorService.submit(new Callable()
{
public Object call() throws Exception{
System.out.println("Asynchronous Callable");
return "Callable Result";
}
});
System.out.println("future.get() = " + future.get());The Future returned by the submit() method. Via this object you can obtain the result returned by the Callable.call() method, once it is executed. The above code example will output this:
Asynchronous Callable future.get() = Callable Result
invokeAny()
TheinvokeAny() method takes a collection of Callable objects, or subinterfaces of Callable. Invoking this method does not return a Future, but returns the result of one of the Callable objects. You have no guarantee about which of the Callable's results you get. Just one of the ones that finish. If one of the tasks complete (or throws an exception), the rest of the
Callable's are cancelled. Here is a code example:
ExecutorService executorService = Executors.newSingleThreadExecutor(); Set<Callable<String>> callables = new HashSet<Callable<String>>(); callables.add(new Callable<String>()
{
public String call() throws Exception{
return "Task 1";
}
});callables.add(new Callable<String>()
{
public String call() throws Exception {
return "Task 2";
}
});
callables.add(new Callable<String>()
{
public String call() throws Exception{
return "Task 3";
}
});
String result = executorService.invokeAny(callables);
System.out.println("result = " + result);
executorService.shutdown();This code example will print out the object returned by one of the
Callable's in the given collection. I have tried running it a few times, and the result changes. Sometimes it is "Task 1", sometimes "Task 2" etc. invokeAll()
TheinvokeAll() method invokes all of the Callable objects you pass to it in the collection passed as parameter. The invokeAll() returns a list of Future objects via which you can obtain the results of the executions of each Callable. Keep in mind that a task might finish due to an exception, so it may not have "succeeded". There is no way on a
Future to tell the difference. Here is a code example:
ExecutorService executorService = Executors.newSingleThreadExecutor(); Set<Callable<String>> callables = new HashSet<Callable<String>>(); callables.add(new Callable<String>()
{
public String call() throws Exception {
return "Task 1";
}
});callables.add(new Callable<String>()
{
public String call() throws Exception{
return "Task 2";
}
});callables.add(new Callable<String>()
{
public String call() throws Exception {
return "Task 3";
}
});
List<Future<String>> futures = executorService.invokeAll(callables);
for(Future<String> future : futures){
System.out.println("future.get = " + future.get());
}
executorService.shutdown();
No comments:
Post a Comment