Java RecursiveTask fork vs compute

时间:2018-01-29 22:20:00

标签: java multithreading performance java-7 fork-join

我有使用RecursiveTask的febunacci算法代码我在

中找到了它

https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/RecursiveTask.html

代码1

public class Fibonacci extends RecursiveTask<Integer> {
   final int n;
   public Fibonacci (int n) { this.n = n; }
   public Integer compute() {
     if (n <= 1)
        return n;
     Fibonacci  f1 = new Fibonacci(n - 1);
     f1.fork();
     Fibonacci  f2 = new Fibonacci(n - 2);
 return f2.compute() + f1.join();

   }
   public static void main(String args[]){
       ForkJoinPool fjpool = new ForkJoinPool();

        RecursiveTask task = new Fibonacci(30);
        long startTime1=System.currentTimeMillis();;
        Integer O=(Integer) fjpool.invoke(task);
        long endTime1 =  System.currentTimeMillis();
        long duration1 = (endTime1 - startTime1);
        System.out.println(duration1);

   }}

这段代码在83ms执行我修改了它

代码2

public class Fibonacci extends RecursiveTask<Integer> {
   final int n;
   public Fibonacci (int n) { this.n = n; }
   public Integer compute() {
     if (n <= 1)
        return n;
     Fibonacci  f1 = new Fibonacci(n - 1);

     Fibonacci  f2 = new Fibonacci(n - 2);
 return f2.compute() + f1.compute();

   }
   public static void main(String args[]){
       ForkJoinPool fjpool = new ForkJoinPool();

        RecursiveTask task = new Fibonacci(30);
        long startTime1=System.currentTimeMillis();;
        Integer O=(Integer) fjpool.invoke(task);
        long endTime1 =  System.currentTimeMillis();
        long duration1 = (endTime1 - startTime1);
        System.out.println(duration1);

   }}

现在这个代码在20ms内执行可以有人解释为什么第二个更快我读了文档,它说fork是异步执行然后为什么它运行速度慢然后使用compute。

2 个答案:

答案 0 :(得分:0)

第一种解决方案可能表现不佳,因为最小的子任务太小而不值得拆分。

RecursiveTask task = new Fibonacci(30);

相反,与几乎所有fork / join应用程序的情况一样,您需要选择一些最小粒度(例如此处为30),您始终按顺序求解而不是细分。

请记住,当涉及更大的并行化数据集时,Fork / Join框架是巨大的。

来源

https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/RecursiveTask.html

答案 1 :(得分:0)

因为 +compute() 不使用池中的新线程,并且它不在池管理线程中运行。 当池调用许多 RecursiveTasks 时,您将看到 +join() 的并行性优势。那么如果计算方法中有等待或阻塞,它的线程将被其他任务使用。所以线程会更少。