关于页面渲染的不同操作解析:
问题:一般地,对HTML文档进行处理时,当遇到文本标签时,将其绘制到图像缓存中。当遇到图像引用时,先通过网络获取它,然后再将其绘制到图像缓存中。
1. 串行地渲染页面元素,即普通的网页页面中图片和文本同时加载
public class SingleThreadRenderer{
void renderPage(CharSequence source){
renderText(source); //渲染文本
List<ImageData> imageData = new ArrayList<ImageData>();
for(ImageInfo imageInfo : scanForImageInfo(source))
{
imageData.add(imageInfo.downloadImage());
}
for(ImageData data : imageData)
{
renderImage(data);
}
}
}
2. 使用Future等待图像下载,即稍微高级点页面内容加载成功后,等待图片加载。FutureRender使得渲染文本任务与下载图像数据的任务并发地执行。
public class FutureRender{
private final ExecutorService executor = ...;
void renderPage(CharSequence source){
final List<ImageInfo> imageInfos = scanForImageInfo(source);
Callable<List<ImageData>> task =
new Callable<List<ImageData>>(){
public List<ImageData> call(){
List<ImageData> result = new ArrayList<ImageData>();
for(ImageInfo imageInfo : imageInfos)
{
result.add(imageInfo.downloadImage());
}
return result;
}
};
Future<List<ImageData>> future = executor.submit(task);
renderText(source);
try{
List<ImageData> imageData = future.get();
for(ImageData data : imageData)
renderImage(data);
}catch(InterruptedExcepiton e){
//重新设置线程的中断状态
Thread.currentThread().interrupt();
//由于不需要结果,因此取消任务
future.cancel(true);
}catch(ExecutionException e){
throw launderThrowable(e.getCause());
}
}
}
在上个示例中,并行地执行两个不同类型的任务——下载图像与渲染页面。然而,通过对异构任务进行并行化来获得重大的性能提升是很困难的。因为,如果渲染文本的速度远远高于下载图像的速度,那么程序的最终性能与串行执行时的性能差别不大,而代码却变的更复杂了。
只有当大量相互独立且同构的任务可以并发进行处理时,才能体现出将程序的工作负载分配到多个任务中带来的真正性能提升。
3. 使用CompletionService,是页面元素在下载完成后立即显示出来。其中,图片是单个下载完成就立即显示。
CompletionService将Executor和BlockingQueue的功能融合在一起。可以将Callable任务提交给它执行,然后使用类似于队列操作的take和poll等方法来获得已完成的结果,而这些结果会在完成时被封装为Future。ExecutorCompletionService实现了CompletionService,并将计算部分委托给一个Executor。
public class Renderere{
private final ExecutorService executor;
Renderer(ExecutorService executor)
{
this.executor = executor;
}
void renderPage(CharSequence source){
List<ImageInfo> info = scanForImageInfo(source);
CompletionService<ImageData> completionService = new ExecutorCompletionService<ImageData>(executor);
for(final ImageInfo imageInfo : info){
completionService.submit(new Callable<ImageData>() {
public ImageData call(){
return imageInfo.downloadImage();
}
});
}
renderText(source);
try{
for(int t=0, n=info.size(); t<n; t++){
Future<ImageData> f = completionService.take();
ImageData imageData = f.get();
renderImage(imageData);
}
}catch(InterruptedException e){
Thread.currentThread().interrupt();
}catch(ExecutionException e){
throw launderThrowable(e.getCause());
}
}
}
分享到:
相关推荐
《java jdk 7学习笔记》适合java的初中级读者,以及广大java应用开发人员。 作译者 林信良(网名:良葛格) 学历:台湾大学电机工程学系 经历:台湾升阳教育训练技术顾问、专业讲师,oracle授权训练中心讲师 ...
### Java学习笔记知识点总结 #### 一、JVM与内存管理 ...通过以上知识点的总结,我们可以清晰地了解到Java学习笔记中涵盖的主要内容和技术细节,有助于深入理解和掌握Java语言及相关的开发技术。
Java 作为一门广泛使用的编程语言,在软件开发领域占据了极其重要的地位。JDK 1.7(也称为Java 7)是Java发展史上的一个重要里程碑,它不仅继承了前几个版本的优点,还引入了许多新的功能和改进。 #### 二、Java ...
### 深入Java虚拟机JVM类加载学习笔记 #### 一、Classloader机制解析 在Java虚拟机(JVM)中,类加载器(ClassLoader)是负责将类的`.class`文件加载到内存中的重要组件。理解类加载器的工作原理对于深入掌握JVM以及...
通过批处理加载、并行加载等方式可以显著提高数据加载的速度。 #### 8.4 使用动态计算(dynamiccalc) 动态计算是一种提高查询性能的技术,它可以在查询时动态计算结果而不是预先计算所有的数据。 #### 8.5 调整...
- **3.2.2 所需软件**:需要安装JDK(Java Development Kit),因为Hadoop是用Java编写的。 - **3.2.3 安装软件**:下载最新的Hadoop二进制包,并解压缩到指定目录。 **3.3 下载** 从Apache官方网站下载最新的...
1.1 Spark概述:Spark由加州大学伯克利分校AMPLab开发,旨在提供比Hadoop MapReduce更快的数据处理速度。它通过内存计算和优化的 DAG 执行引擎实现了高效的计算性能。 1.2 Spark架构:Spark由Driver、Executor和...
**3.2 应用软件开发** - **编程语言**:C/C++、Java、Python等。 - **软件开发流程**:需求分析、设计、编码、测试、维护等阶段。 #### 四、微型计算机系统设计与实现 **4.1 微处理器设计** - **微处理器设计原则*...
- **Python和Java接口**:除了C++外,OpenCV还为Python和Java提供了接口,使得这些语言的用户也能利用CUDA进行高性能图像处理。 #### 六、版本控制与GitHub GitHub是一个流行的代码托管平台,支持使用Git进行版本...