并行循环
如果一个循环中的每次迭代都是独立的,彼此没有影响,那可以将一个顺序的循环变成一个并行的循环。
//顺序执行
void processSequentially(List<Element> elements){
for (Element e:elements) {
process(e);
}
}
//并行执行
void processInparallel(Executor executor,List<Element> elements){
for (final Element e:elements) {
executor.execute(new Runnable() {
@Override
public void run() {
process(e);
}
});
}
}
顺序执行时,只有当循环中的所有任务全部执行完毕后才会返回。而在并行执行中,只要将任务添加到了Executor执行队列中就可以返回了,任务之后会并发的执行。节省了等待时间。当有任务集时,可以使用ComplectionService。
并行递归
同样的方法可以应用到递归中,将递归中的每次需要计算的任务都提交给Executor队列。比如在二叉树中,对二叉树进行深度优先遍历,并对每个节点中的值进行计算。
//顺序递归
void sequentialRecursive(List<Node<Integer>> nodes, Collection<Integer> results){
for (Node<Integer> node:nodes) {
results.add(node.compute);//任务计算
sequentialRecursive(nodes.getChildren(),results);
}
}
//并行递归
void parallelRecursive(final Executor executor,List<Node<Integer>> nodes, Collection<Integer> results){
for (Node<Integer> node:nodes) {
executor.execute(new Runnable() {
@Override
public void run() {
results.add(node.compute);//任务计算
}
});
sequentialRecursive(nodes.getChildren(),results);
}
}
遍历的过程仍然是顺序的,但是对遍历过程中出现的可能会等待的任务进行了并行执行。可通过以下方法获取计算结果
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.shutdown();
executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);