Java 以最小的开销并行执行同一类中的方法

Java 以最小的开销并行执行同一类中的方法,java,parallel-processing,Java,Parallel Processing,我有一个类算法,它有两个复杂、耗时的方法,比如method1和method2。我必须创建这个类的多个实例,并查询resp。方法1和方法2并行地用于这些实例中的每一个。以下代码基本上实现了这一点: private final List<Algorithm> algorithms; private final ExecutorService executor; private final List<Future<Void>> futures; public A

我有一个类算法,它有两个复杂、耗时的方法,比如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;
}
通过这种方式,我可以简单地将算法实例提交给执行器,但我只能对1个方法执行? 有没有关于如何以干净高效的方式改进此实施的建议?不幸的是,不希望将method1和method2放在两个不同的类中,因为它们高度依赖于彼此的数据结构


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

开销可能很小,但您的代码对于未来的任务来说是不必要的复杂。因此,我建议您使用Callables和Futures来简化和清理代码。简而言之,您可以使用以下方法并在代码中相关的位置插入它们

Callable<Double> c = new Callable<Double> () { ... };
Future<Double> f = executor.submit(c);
Double result = f.get();
Callable c=newcallable(){…};
未来f=执行人提交(c);
双重结果=f.get();

别误会我的意思,但你对“担心开销”的回答是错误的。如果您认为您有性能问题,那么分析应用程序的运行时行为以真正了解发生了什么。换句话说:你真的认为当你的实际计算如此复杂时,创建几个对象的开销会起作用吗?在不了解真正的问题是什么的情况下,不要开始“优化”代码。经常可以看到,编写一些草率的东西和正确地编写一些东西所花费的精力大致相同。由于我经常重复使用我的代码,我宁愿从一开始就学习如何正确地实现它。这就是我的问题。除此之外,我同意这肯定不会成为我实现的瓶颈。太好了,这确实更干净,而且不需要重新分配新对象。谢谢
Callable<Double> c = new Callable<Double> () { ... };
Future<Double> f = executor.submit(c);
Double result = f.get();