我有一個接受一系列查詢的方法,我需要針對不同的搜索引擎Web API(如Google或Yahoo)運行它們。爲了並行化進程,爲每個查詢生成一個線程,最後在join
ed之後,因爲我的應用程序只能繼續之後我的結果爲每查詢。目前,我有東西沿着這些路線:多線程搜索操作
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;
}
}
最近,我發現有一個新 API在Java中做兼職。即,Callable
接口,FutureTask
和ExecutorService
。我想知道這個新API是否應該被使用,如果它們比傳統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,我想知道是否有東西,可以在上面的代碼中是改進了,並且如果它比第一個選項更好(使用Thread
)。有一些我沒有探索的類,例如FutureTask
等等。我很樂意聽到關於此的任何建議。
看起來不錯,我不確定我會改變你的第二個例子。 在你的第一個例子中,我將擴展Runnable而不是Thread,但這只是挑剔。 – 2009-07-19 15:12:19
+1,這對我來說已經夠用了。 – akarnokd 2009-07-19 15:37:20