I have a method that accepts an array of requests, and I need to run them against different search engine web APIs such as Google or Yahoo. To parallelize the process, a stream is created for each request, which is then joined at the end, since my application can continue only after I get the results of each request. I currently have something like that:
public abstract class class Query extends Thread {
private String query;
public abstract Result[] querySearchEngine();
@Override
public void run() {
Result[] results = querySearchEngine(query);
Querier.addResults(results);
}
}
public class GoogleQuery extends Query {
public Result querySearchEngine(String query) {
}
}
public class Querier {
private static ArrayList<Result> aggregatedResults;
public static void addResults(Result[]) {
public static Result[] queryAll(Query[] queries) {
for (Query query : queries) {
query.start();
}
for (Query query : queries) {
query.join();
}
return aggregatedResults;
}
}
I recently discovered that there is a new API in Java for doing parallel jobs. Namely, the interface Callable, FutureTaskand ExecutorService. I was wondering if this new API will be used, and if they are more efficient than traditional ones, Runnableand Thread.
After learning this new API, I came up with the following code (simplified version):
public abstract class Query implements Callable<Result[]> {
private final String query;
public abstract Result[] querySearchEngine();
@Override
public Result[] call() {
return querySearchEngine(query);
}
}
public class Querier {
private ArrayList<Result> aggregatedResults;
public Result[] queryAll(Query[] queries) {
List<Future<Result[]>> futures = new ArrayList<Future<Result[]>>(queries.length);
final ExecutorService service = Executors.newFixedThreadPool(queries.length);
for (Query query : queries) {
futures.add(service.submit(query));
}
for (Future<Result[]> future : futures) {
aggregatedResults.add(future.get());
}
return aggregatedResults;
}
}
API concurrency, , -, , , ( Thread). , , FutureTask .. .