我有一个Java
这样的程序:
List<Callable<String>> todo = new ArrayList<Callable<String>>();
for(;;) {
todo.add(new ParallelCall(id,name));
}
ExecutorService es = Executors.newFixedThreadPool(100);
List<Future<String>> returnList = es.invokeAll(todo);
es.shutdown();
try {
es.awaitTermination(10, TimeUnit.MINUTES);
}
catch (InterruptedException e) {
e.printStackTrace();
}
for(Future<String> fut:returnList) {
if(fut.get()!=null) {
entries.add(fut.get());
}
}
public class ParallelCall implements Callable<String> {
public ParallelCall(Integer id,String name) {
this.id = id;
this.name = name;
}
public String call() throws Exception {
String result=someFunction();
return result;
}
}
此代码执行正常。我记录了当前正在执行的线程数。我发现只有极少数,执行器没有利用理想的内核。某些线程有等待状态,因此当“待办事项”列表变大时需要更多时间才能完成。
有没有办法加快这个过程?
答案 0 :(得分:0)
阅读Amdahl's Law。
摘录:
并行使用多个处理器的程序加速 计算受到连续分数所需时间的限制 该程序。例如,如果一个程序需要20个小时使用一个 处理器核心,以及程序的特定部分 一小时执行不能并行,而剩下的19 小时(95%)的执行时间可以并行化,然后无论如何 有多少处理器专门用于并行执行此操作 程序,最小执行时间不能小于那个关键 一小时。因此,加速限制在最多20倍。
您需要找到可以并行处理的系统的更多部分。简单地增加线程数对执行速度没有影响。事实上,创建,销毁线程是一个昂贵的过程。此外,由于大多数操作系统使用循环技术为每个线程提供公平的机会,因此操作系统将花费大量时间在线程之间切换。这将进一步降低性能。