Operacja wyszukiwania wielowątkowego
Mam metodę, która pobiera szereg zapytań i muszę je uruchamiać w oparciu o różne interfejsy Web API wyszukiwarki, takie jak Google lub Yahoo. Aby zrównoważyć proces, wątek jest tworzony dla każdego zapytania, które jest wtedyjoin
pod koniec, ponieważ moja aplikacja może być kontynuowanapo Mam wynikikażdy pytanie. Obecnie mam coś takiego:
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;
}
}
Niedawno odkryłem, że istniejeNowy API w Javie do wykonywania równoczesnych zadań. MianowicieCallable
berło,FutureTask
iExecutorService
. Zastanawiałem się, czy ten nowy API jest tym, który powinien być używany, a jeśli są bardziej wydajne niż tradycyjne,Runnable
iThread
.
Po przestudiowaniu tego nowego API wymyśliłem następujący kod (wersja uproszczona):
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;
}
}
Jestem nowym użytkownikiem API współbieżności i chciałbym wiedzieć, czy jest coś, co może byćulepszony w powyższym kodzie i jeśli jest lepszy niż pierwsza opcja (użycieThread
). Jest kilka klas, których nie zbadałem, takich jakFutureTask
, et cetera. Chciałbym również usłyszeć jakąkolwiek radę na ten temat.