我有一个接受一系列查询的方法,我需要针对不同的搜索引擎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