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 ...
随机推荐
- CentOS 7 配置 ISCSI 服务器
一.服务器配置 1.安装配置软件: yum install targetcli -y 2.进入配置界面: targetcli ,并进行如下配置: 1) /backstores/block create ...
- sort,uniq,cut,wc命令详解
sortsort 命令对 File 参数指定的文件中的行排序,并将结果写到标准输出.如果 File 参数指定多个文件,那么 sort 命令将这些文件连接起来,并当作一个文件进行排序. sort语法 s ...
- C语言连接mysql -select
C语言实现查询mysql数据库的行数,列的属性,以及每条记录. /* select.c */ #include <stdio.h> #include <stdlib.h> #i ...
- [codeforces821E]Okabe and El Psy Kongroo
题意:(0,0)走到(k,0),每一部分有一条线段作为上界,求方案数. 解题关键:dp+矩阵快速幂,盗个图,注意ll 关于那条语句为什么不加也可以,因为我的矩阵C,就是因为多传了了len的原因,其他位 ...
- Raising Modulo Numbers(ZOJ 2150)
这题其实就是快速求一个高次幂的模. 这是题目的答案 #include<iostream> #include<cmath> using namespace std; ]; ]; ...
- 数据库路由中间件MyCat - 源代码篇(16)
此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 5. 路由模块 真正取得RouteResultset的步骤:AbstractRouteStrategy的ro ...
- Note: ENDBOX: Scalable Middlebox Functions Using Client-Side Trusted Execution
ENDBOX enable secure networking by client-Side trusted execution. What ENDBOX is a scalable middlebo ...
- 图的最小切隔问题Minimum Cuts
前提条件是这样的:输入一个图(可以是有向图,也可以是无向图,允许平行边存在),我们要做的事情是将这个图切割成两个子图,(切割的定义:将图中的所有顶点分为两个集合A和B,要求这两个集合非空)假设这个图中 ...
- bzoj 3722: PA2014 Final Budowa
3722: PA2014 Final Budowa Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 303 Solved: 108[Submit][St ...
- [Xcode 实际操作]四、常用控件-(2)UIButton图片按钮的使用
目录:[Swift]Xcode实际操作 本文将演示图片按钮的使用 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import UIKit class ViewCo ...