Java并发(六):并发策略
通过多次优化实例来了解选择并发策略的正确姿势
通过模拟浏览器程序的渲染页面(Page-Rendering)功能,为了方便,假设HTML页面只会包含标签文本和图片以及URL;
第一个版本:串行加载页面元素
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);
}
}
存在的问题:浏览器加载图片之前需要下载图片,此时如果存在网络拥塞,那么此时的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<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(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<ImageInfo> info = scanForImageInfo(source);
CompletionService<ImageData> completionService = new ExecutorComplementService<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 launderThrowbale(e.getCause());
}
}
}
经过第二次的改进,页面更加“响应式”,每个图片都会在下载完成后直接加载渲染至页面,同时异步加载HTML中的文本和URL,使用户获得更加动态的界面;
Java并发(六):并发策略的更多相关文章
- java处理高并发高负载类网站的优化方法
java处理高并发高负载类网站中数据库的设计方法(java教程,java处理大量数据,java高负载数据) 一:高并发高负载类网站关注点之数据库 没错,首先是数据库,这是大多数应用所面临的首个SPOF ...
- [转]java处理高并发高负载类网站的优化方法
本文转自:http://www.cnblogs.com/pengyongjun/p/3406210.html java处理高并发高负载类网站中数据库的设计方法(java教程,java处理大量数据,ja ...
- java之高并发与多线程
进程和线程的区别和联系 从资源占用,切换效率,通信方式等方面解答 线程具有许多传统进程所具有的特征,故又称为轻型进程(Light—Weight Process)或进程元:而把传统的进程称为重型进程(H ...
- JAVA多线程和并发基础面试问答(转载)
JAVA多线程和并发基础面试问答 原文链接:http://ifeve.com/java-multi-threading-concurrency-interview-questions-with-ans ...
- [转] JAVA多线程和并发基础面试问答
JAVA多线程和并发基础面试问答 原文链接:http://ifeve.com/java-multi-threading-concurrency-interview-questions-with-ans ...
- JAVA多线程和并发基础面试问答
转载: JAVA多线程和并发基础面试问答 多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一.在这里,从面试的角度列出了大部分重要的问题,但是你仍然应该牢固的掌握Java多线程基础知识来对 ...
- 【多线程】JAVA多线程和并发基础面试问答(转载)
JAVA多线程和并发基础面试问答 原文链接:http://ifeve.com/java-multi-threading-concurrency-interview-questions-with-ans ...
- Java 多线程 (并发)总结
一.概念 1. 维基百科解释 进程是什么? http://zh.wikipedia.org/wiki/%E8%BF%9B%E7%A8%8B 线程是什么? http://zh.wikipedia.org ...
- (转)JAVA多线程和并发基础面试问答
JAVA多线程和并发基础面试问答 原文链接:http://ifeve.com/java-multi-threading-concurrency-interview-questions-with-ans ...
随机推荐
- Qt弹出消息对话框
添加头文件 #include <QMessageBox> if(ui->lineEditXStart->text().isEmpty()) //判断lineedit输入内容是否 ...
- 获取服务器IP,客户端IP
客户端IP相关的变量 1. $_SERVER['REMOTE_ADDR']; 客户端IP,有可能是用户的IP,也有可能是代理的IP. 2. $_SERVER['HTTP_CLIENT_IP']; 代理 ...
- Luogu 3825 [NOI2017]游戏
Luogu的spj现在挂了,要去其他OJ提交. 2-SAT 发现如果不考虑$x$的情况,这就成为一个2-SAT的裸题了,我们有$O(n + m)$的方法可以解决它. 那加上$x$的情况怎么弄……岂不是 ...
- 1.7 xss之同源策略与跨域访问
同源策略: 同源策略 在web应用的安全模型中是一个重要概念.在这个策略下,web浏览器允许第一个页面的脚本访问第二个页面里的数据,但是也只有在两个页面有相同的源时.源是由URI,主机名,端口号组合而 ...
- 解决spring mybatis 整合后mapper接口注入失败
spring整合mybatis,在dao层我们只写一个接口,配置相应的*mapper.xml文件, 报如下错误: org.springframework.beans.factory.Unsatisfi ...
- Ocelot(二)- 请求聚合与负载均衡
Ocelot(二)- 请求聚合与负载均衡 作者:markjiang7m2 原文地址:https://www.cnblogs.com/markjiang7m2/p/10865511.html 源码地址: ...
- Head First Python 1-4章学习感悟
一.学习知识总结 (1)迭代 range(起始值,结束值,步长):包含起始值,不包含结束值,步长为正数 (2)导入模块 from datetime import datetime (3 ...
- Zjoi2011 看电影
最近在学习一些概率的东西.. 一个随机试验称为 Laplace 试验,当且仅当它满足如下两个条件: (ⅰ) 试验结果 (样本点) 的个数是有限的.(Ω 是有限集) (ⅱ) 任意两个基本事件的概率均相等 ...
- scapy框架
性能相关 在编写爬虫时,性能的消耗主要在IO请求中,当单进程单线程模式下请求URL时必然会引起等待,从而使得请求整体变慢. import requests def fetch_async(url): ...
- C#正则表达式快速入门
作者将自己在学习正则表达式中的心得和笔记作了个总结性文章,希望对初学C#正则表达式的读者有帮助. [内容] 什么是正则表达式 涉及的基本的类 正则表达式基础知识 构建表达式基本方法 编写一个检验程序 ...