Alright, possible a naive question here. I have a service that needs to log into multiple network devices, run a command on each and collect the results. For speed, rather
public List<String> getCommandResults(String command) {
FutureTask task = new FutureTask(new CommandTask(command))
taskExecutor.execute(task);
return task.get(); //or task.get(); return commandResults; - but it not a good practice
}
The TaskExecutor
interface is a fire-and-forget interface, for use when you don't care when the task finishes. It's the simplest async abstraction that Spring offers.
There is , however, an enhanced interface, AsyncTaskExecutor, which provides additional methods, including submit()
methods that return a Future
, which let you wait on the result.
Spring provides the ThreadPoolTaskExecutor class, which implement both TaskExecutor
and AsyncTaskExecutor
.
In your specific case, I would re-implement the Runnable
as a Callable
, and return the commandResults
from the Callable.call()
method. The getCommandResults
method can then be reimplemented as:
public List<String> getCommandResults(String command) {
Future<List<String>> futureResults = taskExecutor.submit(new CommandTask(command));
return futureResults.get();
}
This method will submit the task asynchronously, and then wait for it to complete before returning the results returned from the Callable.call()
method. This also lets you get rid of the commandResults
field.