Java RecursiveTask 分叉与计算
Java RecursiveTask fork vs compute
我有使用 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);
}}
此代码在 83 毫秒内执行,我对其进行了修改
代码 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);
}}
现在这段代码在 20 毫秒内执行,有人可以解释为什么第二个更快我阅读了文档它说 fork 异步执行然后为什么它 运行 比使用计算慢。
第一个解决方案可能执行不佳,因为最小的子任务太小,不值得拆分。
RecursiveTask task = new Fibonacci(30);
相反,与几乎所有 fork/join 应用程序的情况一样,您会选择一些最小粒度(例如这里的 30),您总是按顺序解决而不是细分。
请记住,Fork/Join 框架在并行处理更大的数据集时非常庞大。
来源
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/RecursiveTask.html
因为 +compute() 不使用池中的新线程,而且它不是 运行 在池管理的线程中。
当池调用许多 RecursiveTask 时,您将看到 +join() 的并行性优势。那么如果compute方法中有等待或者阻塞,它的线程就会被其他任务使用。所以线程会更少。
我有使用 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);
}}
此代码在 83 毫秒内执行,我对其进行了修改
代码 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);
}}
现在这段代码在 20 毫秒内执行,有人可以解释为什么第二个更快我阅读了文档它说 fork 异步执行然后为什么它 运行 比使用计算慢。
第一个解决方案可能执行不佳,因为最小的子任务太小,不值得拆分。
RecursiveTask task = new Fibonacci(30);
相反,与几乎所有 fork/join 应用程序的情况一样,您会选择一些最小粒度(例如这里的 30),您总是按顺序解决而不是细分。
请记住,Fork/Join 框架在并行处理更大的数据集时非常庞大。
来源
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/RecursiveTask.html
因为 +compute() 不使用池中的新线程,而且它不是 运行 在池管理的线程中。 当池调用许多 RecursiveTask 时,您将看到 +join() 的并行性优势。那么如果compute方法中有等待或者阻塞,它的线程就会被其他任务使用。所以线程会更少。