构建高效的并行计算
1,在程序开发中我们经常会对异构的任务进行并行化处理,例如一个线程负责数据下载,另一个线程响应ui操作
2,但是有时候多个异构的任务并行并不能保证程序的效率,例如数据下载需要1秒,数据计算需要10秒,那么将这两个任务并行处理也只能提高9%的效率
3,只有当大量相互独立且同构的任务可以并行处理时,才能体现出将程序的工作负载分配到多个任务中带来的真正性能提升
示例代码如下
public abstract class ComputeSample<IN, OUT, DATA> {
/**
* 可缓存的线程池,
* 如果线程池的当前规模超过了处理需求时,那么将回收空闲的线程,
* 当需求增加是,则可以添加性的线程,
* 线程池的规模不存在任何的限制
*/
private final ExecutorService executor = Executors.newCachedThreadPool();
public void compute(IN param) {
final List<DATA> datas = scanForData(param);
// 通过executor管理线程池,
// 通过submit提交任务Callable,
// 通过BlockingQueue管理计算完成的结果
CompletionService<OUT> completionService =
new ExecutorCompletionService<OUT>(executor);
for (final DATA data : datas){
completionService.submit(new Callable<OUT>() {
public OUT call() {
return doCompute(data);
}
});
}
try {
for (int t = 0, n = datas.size(); t < n; t++) {
// take和poll方法是委托给了BlockingQueue的
Future<OUT> f = completionService.take();
// 获得各个计算结果
OUT imageData = f.get();
doSomething(imageData);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (ExecutionException e) {
throw launderThrowable(e.getCause());
}
}
// 构建计算参数
abstract List<DATA> scanForData(IN param);
// 耗时的计算过程
abstract OUT doCompute(DATA param);
// 计算结果处理
abstract void doSomething(OUT param);
}