我正在用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 。我怎么能解决这个问题?
谢谢你
答案 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]);
}
}
这种方法与您的方法一样快(因为它跳过副本并且原子非常快),但保证最终处理所有索引。正如您可能看到的那样:与其他实现相比,这种方法更容易编码。 ;)