我目前正在检查Java中多线程的行为,并且我得到了意想不到的结果。
这就是我正在做的事情:
这是我得到的结果(N个线程的总执行时间):
200 x 200的50个矩阵:
600 x 600的50个矩阵:
1000x1000的50个矩阵:
对于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");
}
答案 0 :(得分:0)
正如@ C-Otto的评论所说,你在多个线程上多次运行任务:
for(int i = 0; i < nThreads; i++) { // <-- n threads are created
System.out.println("Running thread #" + (i+1));
executor.submit(new Runnable(){
public void run(){
for(int[][] graph: graphs) { // <-- operating on the whole list
FloydWarshall f = new FloydWarshall(graph);
f.checkConsistency();
}
}
});
}
因此,在查看代码时,您所看到的行为与预期一致。因为您只是创建n
个线程,这些线程全部同时执行整个列表。执行时间的缺点来自JVM必须加载的额外负载(例如,创建一个新的线程,执行整个算法等)。
但你可能想要的是平衡负载到n
个线程,因此每个线程只能处理整个(1/nth
)的一小部分。
因此,您可能需要定义一些逻辑来分割源(例如Spliterator
,ForkJoinPool
或Streams
),然后再次测量时间。