Java并发之递归算法并行化
一.递归算法的并行化
1.如果在循环中包含了一些密集型计算,或者需要执行可能阻塞的I/O操作,那么只要每次迭代是独立的,都可以对其进行并行化。
2.如果循环中的迭代操作都是独立的,并且不需要等待所有迭代操作都完成后再继续执行,那么就可以使用Executor将串行循环转化为并行循环。如下:
//串行循环
void processSequentially(List<Element> elements){
for(Element e:elements)
process(e);
}
//将上面的串行循环转化为并行执行
void processInParallel(Executor exec , List<Element> elements){
for(final Element e: elements)
exec.execute(new Runnable(){
public void run(){
process(e); }
});
}
上面两个方法中,显然调用后者能更快的返回,因为processInParaller会再所有下载任务都进入了Executor的队列后就立即返回,而不会等待任务全部完成才返回。
所以我们有:当串行循环中的各个迭代操作之间彼此独立,并且每个迭代操作执行的工作量比管理一个新任务时带来的开销更多,那么这个串行循环就适合并行化。
3.同样在一些递归设计中也可以采用并行化的方式来加快执行速度:
//递归遍历树的节点
public<T> void sequentialRecursive(List<Node<T>> node,Collection<T> results){
for(Node<T> n:nodes){
results.add(n.compute());//将节点的数据存入results中
sequentialRecursive(n.getChildren(),results);//递归遍历下一个
}
}
//递归遍历转并行遍历
public<T> void parallelRecursive(final Executor exec ,List<Node<T>> nodes,
final Collection<T> results){
for(final Node<T> n:nodes){
exec.execute(new Runnable(){
public void run(){
results.add(n.compute());
}
});
parallelRecursive(exec,n.getChildren(),results);
}
}
当parallelRecursive返回时,树中的所有节点都已经访问过了,并且每个节点的计算任务也已经放入Executor的工作队列。 我们可以通过以下方式来等待所有的结果:
public<T> Collection<T> getParallelResults