Fork/Join点点滴滴之一RecursiveTask

继续谈谈Fork/Join框架,今天我们主要看看RecursiveTask的使用方法,以及与之有关的有趣的事情。

例子2 RecursiveTask应用实例

除了 RecursiveAction,Fork/Join 框架还提供了其他 ForkJoinTask 子类:带有返回值的 RecursiveTask。从 RecursiveTask 继承的子类同样需要重载 protected void compute() 方法。与 RecursiveAction 稍有不同的是,它可使用泛型指定一个返回值的类型。下面,我们来看看如何使用 RecursiveTask 的子类。

原文代码:

 

class Fibonacci extends RecursiveTask<Integer> {

    final int n;

    Fibonacci(int n) {
        this.n = n;
    }

    private int compute(int small) {
        final int[] results = {1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89};
        return results[small];
    }

    public Integer compute() {
        if (n <= 10) {
            return compute(n);
        }
        
        Fibonacci f1 = new Fibonacci(n - 1);
        Fibonacci f2 = new Fibonacci(n - 2);
        f1.fork();
        f2.fork();
        return f1.join() + f2.join();
    }

    public static void main(String... args) throws InterruptedException, ExecutionException {
        ForkJoinTask<Integer> fjt = new Fibonacci(45);
        ForkJoinPool fjpool = new ForkJoinPool();
        Future<Integer> result = fjpool.submit(fjt);
        System.out.println(result.get());
    }
}

Copy到IDE中,上面代码斜体部分,频频亮出红叉,于是翻看API文档,发现API发生一些变化, 具体修改如下:

 

修改一次后的代码:

 

package fj;
import java.util.concurrent.ExecutionException;
import jsr166y.ForkJoinPool;
import jsr166y.ForkJoinTask;
import jsr166y.RecursiveTask;

class Fibonacci extends RecursiveTask<Integer> {

    final int n;

    Fibonacci(int n) {
        this.n = n;
    }

    private int compute(int small) {
        final int[] results = {1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89};
        return results[small];
    }

    public Integer compute() {
        if (n <= 10) {
            return compute(n);
        }
       
        Fibonacci f1 = new Fibonacci(n - 1);
        Fibonacci f2 = new Fibonacci(n - 2);
        f1.fork();
        f2.fork();
        return f1.join() + f2.join();
    }

    public static void main(String... args) throws InterruptedException, ExecutionException {
        ForkJoinTask<Integer> fjt = new Fibonacci(40);
        ForkJoinPool fjpool = new ForkJoinPool();
        fjpool.execute(fjt);
        Integer resultInt = fjt.get();
        System.out.println(resultInt);
    }
}

  总算没有烦人的红叉了,心里暗爽着呢,抓紧按下运行文件……DOWN!

 

Exception in thread "ForkJoinPool-1-worker-2009" java.lang.OutOfMemoryError: Java heap space
        at jsr166y.ForkJoinWorkerThread.onStart(ForkJoinWorkerThread.java:345)
        at jsr166y.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:310)
生成已停止(总时间:5 秒)

  怎么了?怎么会出现这种问题呢?习惯性的翻看RecursiveTask API文档,它也给出同样的例子只是有几句代码不同:

 

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

 

 

 

照葫芦画瓢,再次修改后的代码:

 

package fj;

import java.util.concurrent.ExecutionException;
import jsr166y.ForkJoinPool;
import jsr166y.ForkJoinTask;
import jsr166y.RecursiveTask;

class Fibonacci extends RecursiveTask<Integer> {

    final int n;

    Fibonacci(int n) {
        this.n = n;
    }

    private int compute(int small) {
        final int[] results = {1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89};
        return results[small];
    }

    public Integer compute() {
        if (n <= 10) {
            return compute(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) throws InterruptedException, ExecutionException {
        ForkJoinTask<Integer> fjt = new Fibonacci(40);
        ForkJoinPool fjpool = new ForkJoinPool();
        fjpool.execute(fjt);
        Integer resultInt = fjt.get();
        System.out.println(resultInt);
    }
}

  运行结果:

165580141
成功生成(总时间:0 秒)

  总算是得出不知道正错的满意结果来了。但是到底是由于什么原因导致的?

 

 

你可能感兴趣的:(thread,框架,ide)