-2
class{

...

     method(x,y){

...

     method(x-1,y);  //own thread for recursion
     method(x,y-1);  //own thread for recursion
     }
}

我想执行线程代码部分,我如何在 java 中对这些部分进行签名。

4

2 回答 2

3

你看过内置的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));
    }

}

这里要注意的大事:

  1. 你必须有一种方法来停止递归(在这个例子中,当你只对一个元素求和时)

  2. 您应该将 .compute() 用于减少的一侧,然后将 .fork() 用于另一侧,并使用 .join() 来获得它的价值。

于 2012-06-29T10:34:36.240 回答
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); 
 }
于 2012-06-29T10:35:28.470 回答