class{
...
method(x,y){
...
method(x-1,y); //own thread for recursion
method(x,y-1); //own thread for recursion
}
}
我想执行线程代码部分,我如何在 java 中对这些部分进行签名。
class{
...
method(x,y){
...
method(x-1,y); //own thread for recursion
method(x,y-1); //own thread for recursion
}
}
我想执行线程代码部分,我如何在 java 中对这些部分进行签名。
你看过内置的java设施吗?如果您使用的是 java 7,则并行递归很容易:
javadocs 包含经典斐波那契问题的解决方案。
更新 这是对数组求和的示例。我并不是说放入 RecursiveTask 是最有效的方法,但它是如何使用它的一个很好的例子。
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
public class Sum extends RecursiveTask<Long> {
private static final long serialVersionUID = 1548240649873455442L;
private int arr[];
private int hi;
private int lo;
public Sum(int arr[]) {
this.arr = arr;
this.lo = 0;
this.hi = arr.length-1;
}
private Sum(int arr[], int lo, int hi) {
this.arr = arr;
this.hi = hi;
this.lo = lo;
}
@Override
protected Long compute() {
if (lo == hi) {
return Long.valueOf(arr[lo]);
}
else {
int mid = (hi+lo)/2;
Sum sumleft = new Sum(arr, lo, mid);
Sum sumright = new Sum(arr, mid+1, hi);
sumleft.fork();
return sumright.compute().longValue() + sumleft.join().longValue();
}
}
public static void main(String args[]) throws Exception {
ForkJoinPool pool = new ForkJoinPool();
int arr[] = new int[] { 1, 2, 3, 4, 5 };
Sum sum = new Sum(arr);
System.out.println(pool.invoke(sum));
}
}
这里要注意的大事:
你必须有一种方法来停止递归(在这个例子中,当你只对一个元素求和时)
您应该将 .compute() 用于减少的一侧,然后将 .fork() 用于另一侧,并使用 .join() 来获得它的价值。
小心这样的线程场景。第一个冲动是写这样的东西:
Thread t1 = new Thread(new Runnable() {
public void run() {
method(x-1,y);
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
method(x,y-1);
}
});
t1.start();
t2.start();
//...
t1.join();
t2.join();
这将满足您的要求,但不幸的是,由于该方法是递归的,因此线程生成将很快失去控制并过度订阅系统,因为线程将在每个递归级别生成。
您将需要设置一个阈值,然后在达到阈值时切换到顺序调用:
if(currentLevel < threshold) {
Thread t1 = new Thread(new Runnable() {
public void run() {
method(x-1,y,currentLevel + 1);
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
method(x,y-1,currentLevel + 1);
}
});
t1.start();
t2.start();
//...
t1.join();
t2.join();
} else {
method(x-1,y);
method(x,y-1);
}