1

我想知道是否可以生成每个loop iteration(每个都单独iteration生成thread)并最终收集结果。考虑这个例子,没有什么特别的。只是一个简单的for-loop,但想法是扩展它。正文for loop无所谓,我只是填了一些代码。但基本上假设它有一些昂贵的计算,每次迭代需要几分钟才能完成。所以我想在一个单独的线程中进行每个循环计算。

public class Threadspawns {

    private double[] arr = new double[4];

    public void calculations(){
        for (int i =2; i < 6; i++){
                   //expensive calculation
            arr[i-2]=Math.pow(i,500);
        }
    }

    public static void main(String[] args){
        Threadspawns t = new Threadspawns();
        long start = System.currentTimeMillis();
        t.calculations();
        long end = System.currentTimeMillis();
        System.out.println(Arrays.toString(t.arr));
        System.out.println("time taken "+ (end-start));

    }

}

同样,如果可以将它们实际拆分recursive calls为多个线程并在它们返回时收集它们。例子是斐波那契

public static int fibonacci(int n){
        if (n==0)
            return 0;
        if (n==1)
            return 1;
        return fibonacci(n-2)+fibonacci(n-1);
    }

斐波那契递归方法可能无法完成。但是如果可能的话,线程之间并行递归调用的任何其他示例都会很高兴知道。

PS:我有基本的知识Thread and Runnable,但想知道以上是否可行

4

1 回答 1

1

将昂贵的计算转移到 Callable 任务中的第一个要求的解决方案。希望它发现它有用:

import java.util.Arrays;
import java.util.concurrent.*;

public class Threadspawns {
    private final int THREAD_COUNT = 8;
    private final int CALCULATION_COUNT = 60000;
    private double[] arr = new double[CALCULATION_COUNT];

    public void calculations() {
        ExecutorService executorService = Executors.newFixedThreadPool(THREAD_COUNT);
        ExecutorCompletionService<Double> completionService = new ExecutorCompletionService<Double>(executorService);
        for (int i = 2; i < CALCULATION_COUNT; i++) {
            completionService.submit(new Calculation(i));
        }

        //Get from all Future tasks till all tasks completed
        for (int i = 2; i < CALCULATION_COUNT; i++) {
            try {
                arr[i] = completionService.take().get();
            } catch (InterruptedException e) {
                e.printStackTrace();  //do something
            } catch (ExecutionException e) {
                e.printStackTrace();  //do something
            }
        }
    }

    private static class Calculation implements Callable<Double> {
        private final int num;

        private Calculation(int num) {
            this.num = num;
        }

        @Override
        public Double call() throws Exception {
            return Math.pow(num, 500);
        }
    }

    public static void main(String[] args) {
        Threadspawns t = new Threadspawns();
        long start = System.currentTimeMillis();
        t.calculations();
        long end = System.currentTimeMillis();
        System.out.println(Arrays.toString(t.arr));
        System.out.println("time taken " + (end - start));
    }
}
于 2013-12-05T01:43:36.313 回答