8.5 递归算法的并行化

我们对6.3节的页面绘制程序进行了一系列的改进以便不断发掘可利用的并行性。第一次是使程序完全串行执行,第二次虽然使用了两个线程,但仍然是串行地下载所有图像:在最后一次实现中将每个图像的下载操作视为一个独立任务,从而实现了更高的并行性。如果在循环体中包含了一些密集计算,或者需要执行可能阻塞的I/O操作,那么只要每次迭代是独立的,都可以对其进行并行化。

如果循环中的迭代操作都是独立的,并且不需要等待所有的迭代操作都完成再继续执行,那么就可以使用Executor将串行循环转化为并行循环,在程序清单8-10的processSequentially和processInParallel中给出了这种方法。

程序清单8-10 将串行执行转换为并行执行

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);}

});

}

调用processInParallel比调用processSequentially能更快地返回,因为processInParallel会在所有下载任务都进入了Executor的队列后就立即返回,而不会等待这些任务全部完成。如果需要提交一个任务集并等待它们完成,那么可以使用ExecutorService.invokeAll,并且在所有任务都执行完成后调用CompletionService来获取结果,如第6章的Renderer所示。 ...

Get Java并发编程实战 now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.