Многопоточная операция поиска

У меня есть метод, который принимает массив запросов, и мне нужно запустить их для различных веб-API поисковых систем, таких как Google или Yahoo. Чтобы распараллелить процесс, для каждого запроса создается поток, который затемjoinEd в конце, так как мое приложение может только продолжитьafter У меня есть результатыevery запрос. В настоящее время у меня есть что-то вроде этого:

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;
    }
}

Недавно я обнаружил, чтоnew API в Java для выполнения параллельных заданий. А именно,Callable интерфейс,FutureTask а такжеExecutorService, Мне было интересно, если этот новый API является тем, который должен использоваться, и если они более эффективны, чем традиционные,Runnable а такжеThread.

Изучив этот новый API, я разработал следующий код (упрощенная версия):

   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;
        }
    }

Я новичок в этом API параллелизма, и я хотел бы знать, есть ли что-то, что может бытьimproved в приведенном выше коде, и если он лучше, чем первый вариант (используяThread). Есть некоторые классы, которые я не изучал, такие какFutureTaskи так далее. Я также хотел бы услышать любой совет по этому поводу.

Ответы на вопрос(3)

Ваш ответ на вопрос