Multithread-Suchvorgang
Ich habe eine Methode, die eine Reihe von Abfragen akzeptiert, und ich muss sie mit verschiedenen Suchmaschinen-Web-APIs wie Google oder Yahoo ausführen. Um den Prozess zu parallelisieren, wird für jede Abfrage ein Thread erzeugt, die dann sindjoin
am Ende bearbeitet, da meine Bewerbung nur fortgesetzt werden kannnach dem Ich habe die Ergebnisse vonjeden Abfrage. Ich habe derzeit etwas in diese Richtung:
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;
}
}
Vor kurzem habe ich festgestellt, dass es eine gibtNeu API in Java für gleichzeitige Jobs. Nämlich dieCallable
Schnittstelle,FutureTask
undExecutorService
. Ich habe mich gefragt, ob diese neue API diejenige ist, die verwendet werden sollte, und ob sie effizienter ist als die herkömmlichen.Runnable
undThread
.
Nachdem ich diese neue API studiert hatte, kam ich zu folgendem Code (vereinfachte Version):
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;
}
}
Ich bin neu in dieser Parallelitäts-API und möchte wissen, ob es etwas gibt, das sein kannverbessert im obigen Code, und wenn es besser ist als die erste Option (mitThread
). Es gibt einige Klassen, die ich nicht untersucht habe, wie zFutureTask
, und so weiter. Ich würde gerne auch einen Rat dazu hören.