gpt4 book ai didi

java - 以最小的开销并行执行同一类的方法

转载 作者:行者123 更新时间:2023-11-30 08:18:55 27 4
gpt4 key购买 nike

我有一个类算法,它有 2 个复杂、耗时的方法,比如方法 1 和方法 2。我必须创建此类的多个实例,然后进行查询。每个实例的方法 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;
}

令我困扰的是每次调用solveMethod1或solveMethod2时创建的所有FutureTask对象所引起的开销(这种情况经常发生!)。问题是,根据 JavaDoc,你不能重用 FutureTask 对象,即我不能多次执行同一个 FutureTask,所以每次我想执行任何方法时都必须创建该对象的新实例。我考虑过让类 Algorithm 可调用,从而添加一个方法:

@Override
public Double call() throws Exception {
return this.method1();
}

这样我就可以简单地将算法实例提交给执行器,但我只能为 1 个方法执行此操作?关于如何以干净、高效的方式改进这一实现有什么建议吗?不幸的是,我们不希望将 method1 和 method2 放入 2 个不同的类中,因为它们高度依赖于彼此的数据结构。

顺便说一句,这是一个简化的代码片段。在我的真实代码中,method1和method2也可以抛出异常。

最佳答案

开销可能很小,但您的代码因 FutureTasks 而变得不必要的复杂。因此,我建议您使用 Callables & Futures 来简化和清理代码。简而言之,您可以使用以下方法并将它们插入到代码中的相关位置。

Callable<Double> c = new Callable<Double> () { ... };
Future<Double> f = executor.submit(c);
Double result = f.get();

关于java - 以最小的开销并行执行同一类的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29252146/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com