博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java并发(六):并发策略
阅读量:5049 次
发布时间:2019-06-12

本文共 2933 字,大约阅读时间需要 9 分钟。

通过多次优化实例来了解选择并发策略的正确姿势

  通过模拟浏览器程序的渲染页面(Page-Rendering)功能,为了方便,假设HTML页面只会包含标签文本和图片以及URL;

  

  第一个版本:串行加载页面元素

public class SingleThreadRenderer{    void renderPage(CharSequence source){        renderText(Source);        List
imageData = new ArrayList
(); for(ImageInfo imageInfo : scanForImageInfo(source)) imageData.add(imageInfo.downloadImage()); for(ImageData data : ImageData) renderImage(data); }}

  存在的问题:浏览器加载图片之前需要下载图片,此时如果存在网络拥塞,那么此时的CPU几乎没怎么用,大都在等待I/O操作执行完成,也会使用户体验降低:图片没下载完,文字就加载不出来;

 

  改进版本1:使用Future实现页面渲染

/** * @author YHW * @ClassName: FutureRenderer * @Description: * @date 2019/3/28 16:21 */public class FutureRenderer {    private ExecutorService executor ;    void renderPage(CharSequence source){        final List
imageInfos = scanForImageInfo(source); Callable
> task = new Callable
>(){ public List
call(){ List
result = new ArrayList
(); for(ImageInfo imageInfo : imageInfos) result.add(imageInfo.downloadImage()); return result; } }; Future
> future = executor.submit(task); renderText(source); try{ List
imageData = future.get(); for(ImageData data : imageData){ renderImage(data); } }catch(InterruptedException e){ Thread.currentThread().interrupt(); future.cancel(true); }catch(ExecutionException e){ throw launderThrowable(e.getCause()); } }}

  该版本使得页面文本和图片实现异步加载,但还有可以优化的地方,假设渲染文本的速度远大于图片的下载速度(很有可能),那么该版本与串行程序最后的性能差别不大,所以此改进方法对于性能的提升非常有限,而代码却更加复杂,其实在大量相互独立且同构的任务可以并发进行处理时,才能体现出将程序的负载分配带来真正的性能提升;

 

  改进版本2:使用完成服务(CompletionService),其基于Executor和BlockingQueue,可以将Callable任务交给它来执行,再使用类似队列的出队操作来获取结果:

public class Renderer {    private final ExecutorService executor;        Renderer(ExecutorService executor){ this.executor = executor; }    void revderPage(Charquence source){        List
info = scanForImageInfo(source); CompletionService
completionService = new ExecutorComplementService
(executor); for(final ImageInfo imageInfo : info) completionService.submit(new Callable
(){ public ImageData call(){ return imageInfo.downloadImage(); } }); renderText(source); try{ for(int t = 0, n = info.size(); t < n; t++){ Future
f = completionService.take(): ImageData imageData = f.get(); renderImage(imageData); } }catch(InterruptedException e){ Thread。currentThread().interrupt(); }catch(ExecutionException e){ throw launderThrowbale(e.getCause()); } }}

 

  经过第二次的改进,页面更加“响应式”,每个图片都会在下载完成后直接加载渲染至页面,同时异步加载HTML中的文本和URL,使用户获得更加动态的界面;

 

转载于:https://www.cnblogs.com/Joey44/p/10491071.html

你可能感兴趣的文章
MVC Razor
查看>>
软件目录结构规范
查看>>
Windbg调试Sql Server 进程
查看>>
linux调度器系列
查看>>
mysqladmin
查看>>
解决 No Entity Framework provider found for the ADO.NET provider
查看>>
SVN服务器搭建和使用(三)(转载)
查看>>
Android 自定义View (三) 圆环交替 等待效果
查看>>
设置虚拟机虚拟机中fedora上网配置-bridge连接方式(图解)
查看>>
HEVC播放器出炉,迅雷看看支持H.265
查看>>
[置顶] Android仿人人客户端(v5.7.1)——人人授权访问界面
查看>>
Eclipse 调试的时候Tomcat报错启动不了
查看>>
【安卓5】高级控件——拖动条SeekBar
查看>>
ES6内置方法find 和 filter的区别在哪
查看>>
Android入门之文件系统操作(二)文件操作相关指令
查看>>
Android实现 ScrollView + ListView无滚动条滚动
查看>>
Swift 中的指针使用
查看>>
Swift - 使用闭包筛选过滤数据元素
查看>>
alue of type java.lang.String cannot be converted to JSONObject
查看>>
搜索引擎选择: Elasticsearch与Solr
查看>>