【发布时间】:2018-01-08 23:21:30
【问题描述】:
我目前正在检查 Java 中的多线程行为,但得到了意想不到的结果。
这就是我正在做的事情:
- 生成 50 个随机邻接矩阵,大小为 600x600 和 将它们保存到 .txt 文件中
- 读取这些矩阵并使用 N 运行 Floyd Warshall 算法 没有同步的线程(从 1 到 3)。每个线程运行 包含 50 个矩阵的算法。
这是我得到的结果(N 个线程的总执行时间):
50 个 200x200 的矩阵:
- 有 1 个线程:~483 毫秒
- 有 2 个线程:~615 毫秒
- 3 个线程:~741 毫秒
50 个 600x600 的矩阵:
- 有 1 个线程:~9500 毫秒
- 有 2 个线程:~15389 毫秒
- 3 个线程:~16383 毫秒
50 个 1000x1000 的矩阵:
- 有 1 个线程:~43140 毫秒
- 有 2 个线程:~61408 毫秒
- 3 个线程:~76219 毫秒
1、2 或 3 个线程的时间不应该大致相同吗? 为什么会增加?
这是运行 N 个线程的方法:
private static void runThreads(List<int[][]> graphs, int nThreads) throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(nThreads);
Collection<Callable<String>> callables = new ArrayList<Callable<String>>();
for(int i = 0; i < nThreads; i++) {
callables.add(new Callable<String>() {
@Override
public String call() throws Exception {
for(int[][] graph: graphs) {
FloydWarshall f = new FloydWarshall(graph);
f.checkConsistency();
}
return null;
}
});
}
long startTime = System.currentTimeMillis();
List<Future<String>> futures = executor.invokeAll(callables);
executor.shutdown();
long endTime = System.currentTimeMillis();
long totalTime = endTime - startTime;
System.out.println("Total time: " + totalTime + " ms");
}
【问题讨论】:
-
也许 IO 是瓶颈?只是猜测。
-
看起来你运行算法 n 次,其中 n 是线程数。所以更多的线程更多的时间。
-
@C-Otto 这也是我的猜测。这是JVM的限制还是什么?
-
@zhh 这些作为 Runnables 提交给执行者。理论上增加
n不会导致更长的执行时间,前提是硬件可以扩展。 -
另一个建议是寻找正确的方法来进行基准测试,因为仅仅测量时间是不够的,你必须考虑 jvm 预热、jit 优化等等
标签: java multithreading