class{
...
method(x,y){
...
method(x-1,y); //own thread for recursion
method(x,y-1); //own thread for recursion
}
}
我想执行线程代码部分,如何在java中签署这些部分。
答案 0 :(得分:3)
你看过内置的java设施吗?如果你使用的是java 7,那么并行递归很容易:
javadocs包含经典Fibonacci问题的解决方案。
<强>更新强> 这是一个对数组求和的例子。我并不认为放入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()来获取它的值。
答案 1 :(得分:1)
小心这样的线程场景。第一个冲动就是写下这样的东西:
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);
}