Running Multiple Tasks at Once Asynchronously
To coordinate the processing of tasks in an asynchronous manner via a ManagedExecutorService , two or more
tasks that need to be processed should be contained in separate classes or multiple instances of the same
task class. Each of the task classes should implement the java.util.concurrent.Callable and
javax.enterprise.concurrent.ManagedTask interfaces. A task class should include a constructor that enables
a caller to pass arguments that are required to instantiate the object, and should implement a call method, which returns
the information that is needed to construct the report to the client. Two or more such task classes can then be invoked via
the ManagedExecutorService in order to orchestrate the execution and process all results into the required format.
To assemble the tasks for processing, create an ArrayList<Callable> , and add instances of each task to the
array. In the example below, the array is named builderTasks , and instances of two different task types are added to
ArrayList<Callable<AuthorInfo>> builderTasks = new ArrayList<Callable<AuthorInfo>>();
Next, pass the array that has been constructed to the ManagedExecutorService , returning a
List<Future<object>> , which can then be used to process the results.
List<Future<AuthorInfo>> results = mes.invokeAll(builderTasks);
AuthorInfo authorInfo = (AuthorInfo) results.get(0).get();
// Process the results
Suppose you are writing an application that needs the ability to connect a database and retrieve data from two or
more tables to obtain results at the same time. You wish to have the results aggregated before returning them to the
user. Create a builder task that can be used to run two different tasks in parallel. Each of the tasks can retrieve the data
from the different sources, and in the end the data will be merged together and aggregated to formulate the result.
In this case, you need to configure a resource of type javax.enterprise.concurrent.ManagedExecutorService , as
shown in the excerpt from the web.xml below:
This executor is used for the application's builder tasks. This executor has the following
Run Location: Local
Context Info: Local Namespace, Security
In this example, the ManagedExecutorService resource in the application is configured to work with a
resource that has been registered with the application server container and identified by the JNDI name of
concurrent/BuilderExecutor . If you would rather utilize an annotation, then the following @Resource annotation
can be specified to inject a ManagedExecutorService into a class for use within the Runnable .