线程执行部分

时间:2012-06-29 10:29:25

标签: java multithreading

class{

...

     method(x,y){

...

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

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

2 个答案:

答案 0 :(得分:3)

你看过内置的java设施吗?如果你使用的是java 7,那么并行递归很容易:

RecursiveTask

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));
    }

}

这里需要注意的重点是:

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

  2. 您应该在缩减的一侧使用.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); 
 }