【发布时间】:2012-05-14 14:43:44
【问题描述】:
我正在使用两个线程将两个矩阵相乘(但是,该程序也是为按比例编写的,因此我可以使用三个、四个等线程代替)。每个线程计算/完成最终矩阵的一行(或列)的工作。如果一个线程在一行上工作,那么其他线程不应该在该行上工作。它/他们应该移动到下一个可用行。
首先,我不确定我实现问题的方式是否正确。如果你能看到更好的方法,请告诉我。
其次,按照我的做法,每次我测试它(使用不同大小的矩阵——甚至是巨大的矩阵)时,只有一个线程可以完成这项工作。也就是说,每次都是同一个线程访问 run() 方法的同步块。其他线程都进入了run()方法,为什么总是只有一个线程获得锁,做所有的工作?
这是我的运行方法:
public void run() {
System.out.println(Thread.currentThread().getName());
while (i < number of columns in final matrix) {
synchronized (this) {
if (i < number of columns in final matrix) {
for (int j = 0; j < Main.B[0].length; j++) {
for (int k = 0; k < Main.A[0].length; k++) {
Main.C[i][j] += Main.A[i][k] * Main.B[k][j];
}
}
i++;
}
}
}
}
这是我的驱动程序类中创建线程并启动程序的代码:
MyRunnable r = new MyRunnable();
Thread thread1 = new Thread(r);
Thread thread2 = new Thread(r);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException ie) {
System.out.println("\nThe following error occurred: " + ie);
}
}
我想我的问题是双重的——我的方法对于手头的问题是否正确?如果是这样,(如果不是),为什么一个线程总是抓住锁并完成所有工作?我在 20x20 矩阵上检查了最多 6 个线程的程序,并且始终只有一个线程在做这项工作。
【问题讨论】:
-
我一直这样做:启动线程,然后立即等待它们完成工作。这是我在教科书中看到的方法……您有其他建议吗?
-
关于四把锁的评论,不应该是这样。只创建了一个 MyRunnable 实例 (r)。我在线程构造函数中将单个实例传递给每个线程,因此所有线程应该只有一个锁。如果这不正确,请告诉我。
-
@whistler 你是对的。锁。问题是你用
synchronized(this) {锁定了整个区域。这意味着一次只有一个线程可以输入代码,也意味着一次只有一个线程可以计算 -
我也不是 Java 专家 :) 但我很确定 (99%) join() 不是这种情况。
-
一个(长)建议:(1)如果这将是您应用程序中的常见操作,则使用某种类型的执行器以避免创建新线程的开销; (2) 使用 Callable 而不是 Runnable 并让 callable 接受一行和一列,然后返回该操作的结果; (3) 将操作所需的所有Callables提交给Executor; (4) 让主线程将每个可调用的结果组合成最终结果。
标签: java multithreading synchronized matrix-multiplication