Operación de búsqueda multiproceso

Tengo un método que toma una serie de consultas, y tengo que ejecutarlas contra diferentes API web de motores de búsqueda, como la de Google o la de Yahoo. Para paralelizar el proceso, se genera un subproceso para cada consulta, que luego sejoinEd al final, ya que mi aplicación solo puede continuar.después Tengo los resultados decada consulta. Actualmente tengo algo en este sentido:

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) { 
        // access google rest API
    }
}

public class Querier {
    /* Every class that implements Query fills this array */
    private static ArrayList<Result> aggregatedResults;

    public static void addResults(Result[]) { // add to aggregatedResults }

    public static Result[] queryAll(Query[] queries) {
        /* for each thread, start it, to aggregate results */
        for (Query query : queries) {
            query.start();
        }
        for (Query query : queries) {
            query.join();
        }
        return aggregatedResults;
    }
}

Recientemente, he encontrado que hay unanuevo API en Java para hacer trabajos concurrentes. A saber, elCallable interfaz,FutureTask yExecutorService. Me preguntaba si esta nueva API es la que debería usarse y si son más eficientes que las tradicionales.Runnable yThread.

Después de estudiar esta nueva API, se me ocurrió el siguiente código (versión simplificada):

   public abstract class Query implements Callable<Result[]> {
        private final String query; // gets set in the constructor

        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());  // get() is somewhat similar to join?
            }  
            return aggregatedResults;
        }
    }

Soy nuevo en esta API de concurrencia, y me gustaría saber si hay algo que pueda sermejorado en el código anterior, y si es mejor que la primera opción (usandoThread). Hay algunas clases que no exploré, comoFutureTask, etcétera. Me encantaría escuchar cualquier consejo sobre eso también.

Respuestas a la pregunta(3)

Su respuesta a la pregunta