我有一个类算法,它有2个复杂,耗时的方法,比如method1和method2。我必须创建这个类的多个实例,并查询resp。方法1和方法2并行地用于这些实例中的每一个。以下代码几乎实现了这一点:
private final List<Algorithm> algorithms;
private final ExecutorService executor;
private final List<Future<Void>> futures;
public AlgorithmManager(List<Algorithm> algorithms){
this.algorithms=algorithms;
//Define workers
executor = Executors.newFixedThreadPool(Constants.MAXTHREADS); //Creates a threat pool consisting of MAXTHREADS threats
futures=new ArrayList<Future<Void>>(algorithms.size());
}
/**
* Procedure to solve method1 for each algorithm in parallel
*/
public double[] solveMethod1(){
double[] results=new double[algorithms.size()];
List<FutureTask<Double>> taskList=new ArrayList<FutureTask<Double>>();
//submit all the relevant tasks to solve method1
for(Algorithm pp : algorithms){
FutureTask<Double> futureTask = new FutureTask<Double>(new Callable<Double>() {
@Override
public Double call() {
return pp.solveMethod1(); //SolveMethod1
}
});
taskList.add(futureTask);
executor.submit(futureTask);
}
//Query the results of each task one by one
for(int i=0; i<algorithms.size(); i++){
results[i]=taskList.get(i).get();
}
return results;
}
/**
* Procedure to solve method2 for each algorithm in parallel
*/
public int[] solveMethod2(){
int[] results=new double[algorithms.size()];
List<FutureTask<Integer>> taskList=new ArrayList<FutureTask<Integer>>();
//submit all the relevant tasks to solve method1
for(Algorithm pp : algorithms){
FutureTask<Integer> futureTask = new FutureTask<Integer>(new Callable<Integer>() {
@Override
public Integer call() {
return pp.solveMethod2(); //SolveMethod2
}
});
taskList.add(futureTask);
executor.submit(futureTask);
}
//Query the results of each task one by one
for(int i=0; i<algorithms.size(); i++){
results[i]=taskList.get(i).get();
}
return results;
}
困扰我的是每次创建的FutureTask对象引起的开销,每次调用solveMethod1或solveMethod2时(这种情况经常发生!)。问题是,根据JavaDoc,你不能重用FutureTask对象,即我不能多次执行相同的FutureTask,所以每次我想要执行任何方法时,我都必须创建一个新的对象实例。 我已经考虑过使类算法可调,从而添加一个方法:
@Override
public Double call() throws Exception {
return this.method1();
}
这样我就可以简单地将Algorithm实例提交给执行者,但我只能为1个方法执行此操作? 有关如何以干净有效的方式改进此实施的任何建议?不幸的是,将method1和method2放入2个不同的类中是不可取的,因为它们高度依赖于彼此的数据结构。
顺便说一句,这是一个简化的代码片段。在我的实际代码中,method1和method2也可以抛出异常。
答案 0 :(得分:1)
开销可能很小,但使用FutureTasks会使代码不必要地复杂化。所以我建议你使用Callables&amp; amp;来简化和清理你的代码。而是期货。简而言之,您可以使用以下方法并将它们插入代码中相关的位置。
Callable<Double> c = new Callable<Double> () { ... };
Future<Double> f = executor.submit(c);
Double result = f.get();