在多个固定线程中平等分享工作

时间:2013-12-02 15:51:59

标签: java multithreading partitioning

我正在用java制作一个软件,它将LU中的方阵A分解:A = LU。 我正在尝试使用Java Threads与并发

每个DecomposerThread都有 int start int end 作为局部变量。

问题是:给定两个整数 n (代表方阵长度)和 numThr (代表固定数量的线程),循环是什么用几乎相同数量的行实例化每个线程? (矩阵必须“覆盖”形式从0到n-1)

Ex:只有一个帖子

int start = 0; int end = n-1;

    int numThr = 4, n = 2502;
    int [] pool = new int[numThr];

    int passo = n/numThr;
    int old = passo;

    System.out.println("Start: "+(0)+" end: "+(passo));

    for(int i = 1; i<pool.length; i++){

        System.out.println("Start: "+(old+1)+" end: "+(passo*(i+1) - 1));
        old = (passo*(i+1) - 1);;

    }

但结果是:

    Start: 0 end: 625
    Start: 626 end: 1249
    Start: 1250 end: 1874
    Start: 1875 end: 2499

你怎么看,最后一个Thread的结束值是2499而不是 2501 。我怎么能解决这个问题?

谢谢你

3 个答案:

答案 0 :(得分:0)

n/numThr == 2502/4 == 625 remainder 2

所有线程获得625行,2个线程也获得1行。我的Java很可笑,所以我会让你编写代码

答案 1 :(得分:0)

您需要跟踪当前错误。这会逐步完成正确的位置 - 您可能需要在场所使用+/- 1:

public void test() {
  calc(2502, 4);
  calc(5, 4);
}

public void calc(int n, int thr) {
  final int size = n / thr;
  final int err = n % thr;
  int totalErr = 0;
  int start = 0;

  System.out.println("n=" + n + " thr=" + thr + " Size: " + size + " err: " + err);
  for (int i = 0; i < thr; i++) {
    int end = start + size;
    totalErr += err;
    if (totalErr >= thr) {
      end += 1;
      totalErr -= thr;
    }
    System.out.println("Start: " + start + " end: " + end);
    start = end;
  }
}

打印

n=2502 thr=4 Size: 625 err: 2
Start: 0 end: 625
Start: 625 end: 1251
Start: 1251 end: 1876
Start: 1876 end: 2502
n=5 thr=4 Size: 1 err: 1
Start: 0 end: 1
Start: 1 end: 2
Start: 2 end: 3
Start: 3 end: 5

答案 2 :(得分:0)

迭代遍历数组的平滑方法(只要你只是阅读)是每个Thread读取一个正在进行的索引,然后以原子方式递减。好处是您不需要事先拆分数组,也不会人为地强制某些线程处于活动状态,而OS / JVM确定它应该因任何原因而被搁置。

可能的实施:

float[] matrix = new float[n];
final AtomicInteger index = new AtomicInteger(n);

在线程x中:

run() {
  int myIndex;
  while ((myIndex = index.decrementAndGet()) >= 0) {
    compute(matrix[myIndex]);
  }
}

这种方法与您的方法一样快(因为它跳过副本并且原子非常快),但保证最终处理所有索引。正如您可能看到的那样:与其他实现相比,这种方法更容易编码。 ;)