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 ...
随机推荐
- MySQL绿色版的安装步骤
由于工作需要最近要开始研究MySQL了(看来学习都是逼出来的),本人对mysql没有研究,可以说一个小白. 下面就从安装开始吧,虽然网上关于这方面的东西很多,还是需要自己把操作过程写下来. 1.数据库 ...
- 网络编程之socket编程实例
简单实例1 server.c #include <stdio.h> #include <string.h> #include <stdlib.h> #include ...
- ipcs、ipcrm命令
进程间通信概述进程间通信有如下的目的:1.数据传输,一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到几M之间:2.共享数据,多个进程想要操作共享数据,一个进程对数据的修改,其他进程应该 ...
- [poj2135]Farm Tour(最小费用流)
解题关键:最小费用流 代码一:bellma-ford $O(FVE)$ bellman-ford求最短路,并在最短路上增广,速度较慢 #include<cstdio> #include& ...
- Hadoop的namenode和secondnamenode分开部署在不同服务器
一.系统环境: Hadoop 0.20.2.JDK 1.6.Linux操作系统 二.使用背景 网上关于Hadoop的集群配置,很多情况下,都是把namenode和secondnamenode部署在 ...
- windows 服务器安装python及其基本库
步骤如下: 一.安装python软件: 1.进入windows服务器,从网址下载 python-3.5.4-amd64软件 到桌面: 2.在软件点右键,再“”以管理员身份运行“”,输入管理员密码: 3 ...
- 文件格式——fastq格式
fastQ格式 FASTQ是一种存储了生物序列(通常是核酸序列)以及相应的质量评价的文本格式. 他们都是以ASCII编码的.现在几乎是高通量测序的标准格式.NCBI Short Read Archiv ...
- adb devices unauthorized解决方法
有时候使用adb连接手机时,即使打开了usb调试,手机添加了信任,仍然出现unauthorized的提示 解决办法如下: 先上两张stack overflow上面的图片: 很多人可能看不懂.翻一下大概 ...
- ZOJ 3939 The Lucky Week (暴力找规律)
题意:给定一个幸运日,求第 k 个幸运日是多少. 析:由于闰年,每400肯定会循环一次,所以我们就可以先找出每400年会有多少幸运日,是2058个,然后再暴力. 代码如下: #pragma comme ...
- 20169219linux 内核原理与分析第五周作业
进程调度 1. 进程调度是确保进程能有效工作的一个内核子进程.调度程序是像linux这样的多任务操作系统的基础.最大限度地利用处理器时间的原则是,只要有可以执行的进程,那么就总会有进程正在执行.但是只 ...