- 浏览: 47234 次
- 性别:
文章分类
- 全部博客 (103)
- 一致性哈希算法 (1)
- 云计算 (2)
- Cassandra学习 (2)
- Java网络通信与笔记 (14)
- ZooKeeper学习 (1)
- HBase学习 (1)
- Sqoop学习 (1)
- Java网页开发之 (2)
- Java网络通信框架 (5)
- (memcached)分布式内存对象缓存系统 (1)
- Redis学习 (5)
- Shell学习 (14)
- Linux学习 (10)
- MySQL优化 (17)
- C++ (7)
- HTML5 (5)
- Android学习 (5)
- 网络 (2)
- Node.js (1)
- D3.js (1)
- R语言学习 (3)
- Spark (1)
- CAN协议 (2)
- 解决方案 (0)
最新评论
Java通信的几种IO设计
[size=large]阻塞IO
同步阻塞最常用的一种用法,使用也是最简单的,但是 I/O 性能一般很差,CPU 大部分在空闲状态。下面是一个简单的基于TCP的同步阻塞的Socket服务端例子:
@Test
public void testBlockIoSocket() throws Exception
{
ServerSocket serverSocket = new ServerSocket(10002);
Socket socket = null;
try
{
while (true)
{
socket = serverSocket.accept();
System.out.println("socket连接:" + socket.getRemoteSocketAddress().toString());
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(true)
{
String readLine = in.readLine();
System.out.println("收到消息" + readLine);
if("end".equals(readLine))
{
break;
}
//客户端断开连接
socket.sendUrgentData(0xFF);
}
}
}
catch (SocketException se)
{
System.out.println("客户端断开连接");
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
System.out.println("socket关闭:" + socket.getRemoteSocketAddress().toString());
socket.close();
}
}
设计分析:
由于服务器端是单线程的,在第一个连接的客户端阻塞了线程后,第二个客户端必须等待第一个断开后才能连接。
所有的客户端连接在请求服务端时都会阻塞住,等待前面的完成。即使是使用短连接,数据在写入 OutputStream 或者从 InputStream 读取时都有可能会阻塞。这在大规模的访问量或者系统对性能有要求的时候是不能接受的。
阻塞IO + 每个请求创建线程/线程池
通常解决这个问题的方法是使用多线程技术,一个客户端一个处理线程,出现阻塞时只是一个线程阻塞而不会影响其它线程工作;为了减少系统线程的开销,采用线程池的办法来减少线程创建和回收的成本。模式如下图:
每当来一个客户端的连接的时候,我们服务器就new 一个线程来处理它。在服务器的主程序是不阻塞的,阻塞的只是这个线程。这样也是我目前最常用的模式。
在单个线程处理中,我人为的使单个线程read后阻塞5秒,就像前面说的,出现阻塞也只是在单个线程中,没有影响到另一个客户端的处理。
这种阻塞IO的解决方案在大部分情况下是适用的,在出现NIO之前是最通常的解决方案,Tomcat里阻塞IO的实现就是这种方式。但是如果是大量的长连接请求呢?不可能创建几百万个线程保持连接。再退一步,就算线程数不是问题,如果这些线程都需要访问服务端的某些竞争资源,势必需要进行同步操作,这本身就是得不偿失的。
非阻塞IO + IO multiplexing Java从1.4开始提供了NIO工具包,这是一种不同于传统流IO的新的IO方式,使得Java开始对非阻塞IO支持;NIO并不等同于非阻塞IO,只要设置Blocking属性就可以控制阻塞非阻塞。至于NIO的工作方式特点原理这里一概不说,以后会写。模式如下图:
public class NioNonBlockingSelectorTest
{
Selector selector;
private ByteBuffer receivebuffer = ByteBuffer.allocate(1024);
@Test
public void testNioNonBlockingSelector()
throws Exception
{
selector = Selector.open();
SocketAddress address = new InetSocketAddress(10002);
ServerSocketChannel channel = ServerSocketChannel.open();
channel.socket().bind(address);
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_ACCEPT);
while(true)
{
selector.select();
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()) {
SelectionKey selectionKey = iterator.next();
iterator.remove();
handleKey(selectionKey);
}
}
}
private void handleKey(SelectionKey selectionKey) throws IOException
{
ServerSocketChannel server = null;
SocketChannel client = null;
if(selectionKey.isAcceptable())
{
server = (ServerSocketChannel)selectionKey.channel();
client = server.accept();
System.out.println("客户端: " + client.socket().getRemoteSocketAddress().toString());
client.configureBlocking(false);
client.register(selector, SelectionKey.OP_READ);
}
if(selectionKey.isReadable())
{
client = (SocketChannel)selectionKey.channel();
receivebuffer.clear();
int count = client.read(receivebuffer);
if (count > 0) {
String receiveText = new String( receivebuffer.array(),0,count);
System.out.println("服务器端接受客户端数据--:" + receiveText);
client.register(selector, SelectionKey.OP_READ);
}
}
}
}
Java NIO提供的非阻塞IO并不是单纯的非阻塞IO模式,而是建立在Reactor模式上的IO复用模型;在IO multiplexing Model中,对于每一个socket,一般都设置成为non-blocking,但是整个用户进程其实是一直被阻塞的。只不过进程是被select这个函数阻塞,而不是被socket IO给阻塞,所以还是属于非阻塞的IO。
网络IO优化
对于网络IO有一些基本的处理规则如下:
1。减少交互的次数。比如增加缓存,合并请求。
2。减少传输数据大小。比如压缩后传输、约定合理的数据协议。
3。减少编码。比如提前将字符转化为字节再传输。
4。根据应用场景选择合适的交互方式,同步阻塞,同步非阻塞,异步阻塞,异步非阻塞。
[/size]
[size=large]阻塞IO
同步阻塞最常用的一种用法,使用也是最简单的,但是 I/O 性能一般很差,CPU 大部分在空闲状态。下面是一个简单的基于TCP的同步阻塞的Socket服务端例子:
@Test
public void testBlockIoSocket() throws Exception
{
ServerSocket serverSocket = new ServerSocket(10002);
Socket socket = null;
try
{
while (true)
{
socket = serverSocket.accept();
System.out.println("socket连接:" + socket.getRemoteSocketAddress().toString());
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(true)
{
String readLine = in.readLine();
System.out.println("收到消息" + readLine);
if("end".equals(readLine))
{
break;
}
//客户端断开连接
socket.sendUrgentData(0xFF);
}
}
}
catch (SocketException se)
{
System.out.println("客户端断开连接");
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
System.out.println("socket关闭:" + socket.getRemoteSocketAddress().toString());
socket.close();
}
}
设计分析:
由于服务器端是单线程的,在第一个连接的客户端阻塞了线程后,第二个客户端必须等待第一个断开后才能连接。
所有的客户端连接在请求服务端时都会阻塞住,等待前面的完成。即使是使用短连接,数据在写入 OutputStream 或者从 InputStream 读取时都有可能会阻塞。这在大规模的访问量或者系统对性能有要求的时候是不能接受的。
阻塞IO + 每个请求创建线程/线程池
通常解决这个问题的方法是使用多线程技术,一个客户端一个处理线程,出现阻塞时只是一个线程阻塞而不会影响其它线程工作;为了减少系统线程的开销,采用线程池的办法来减少线程创建和回收的成本。模式如下图:
每当来一个客户端的连接的时候,我们服务器就new 一个线程来处理它。在服务器的主程序是不阻塞的,阻塞的只是这个线程。这样也是我目前最常用的模式。
在单个线程处理中,我人为的使单个线程read后阻塞5秒,就像前面说的,出现阻塞也只是在单个线程中,没有影响到另一个客户端的处理。
这种阻塞IO的解决方案在大部分情况下是适用的,在出现NIO之前是最通常的解决方案,Tomcat里阻塞IO的实现就是这种方式。但是如果是大量的长连接请求呢?不可能创建几百万个线程保持连接。再退一步,就算线程数不是问题,如果这些线程都需要访问服务端的某些竞争资源,势必需要进行同步操作,这本身就是得不偿失的。
非阻塞IO + IO multiplexing Java从1.4开始提供了NIO工具包,这是一种不同于传统流IO的新的IO方式,使得Java开始对非阻塞IO支持;NIO并不等同于非阻塞IO,只要设置Blocking属性就可以控制阻塞非阻塞。至于NIO的工作方式特点原理这里一概不说,以后会写。模式如下图:
public class NioNonBlockingSelectorTest
{
Selector selector;
private ByteBuffer receivebuffer = ByteBuffer.allocate(1024);
@Test
public void testNioNonBlockingSelector()
throws Exception
{
selector = Selector.open();
SocketAddress address = new InetSocketAddress(10002);
ServerSocketChannel channel = ServerSocketChannel.open();
channel.socket().bind(address);
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_ACCEPT);
while(true)
{
selector.select();
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()) {
SelectionKey selectionKey = iterator.next();
iterator.remove();
handleKey(selectionKey);
}
}
}
private void handleKey(SelectionKey selectionKey) throws IOException
{
ServerSocketChannel server = null;
SocketChannel client = null;
if(selectionKey.isAcceptable())
{
server = (ServerSocketChannel)selectionKey.channel();
client = server.accept();
System.out.println("客户端: " + client.socket().getRemoteSocketAddress().toString());
client.configureBlocking(false);
client.register(selector, SelectionKey.OP_READ);
}
if(selectionKey.isReadable())
{
client = (SocketChannel)selectionKey.channel();
receivebuffer.clear();
int count = client.read(receivebuffer);
if (count > 0) {
String receiveText = new String( receivebuffer.array(),0,count);
System.out.println("服务器端接受客户端数据--:" + receiveText);
client.register(selector, SelectionKey.OP_READ);
}
}
}
}
Java NIO提供的非阻塞IO并不是单纯的非阻塞IO模式,而是建立在Reactor模式上的IO复用模型;在IO multiplexing Model中,对于每一个socket,一般都设置成为non-blocking,但是整个用户进程其实是一直被阻塞的。只不过进程是被select这个函数阻塞,而不是被socket IO给阻塞,所以还是属于非阻塞的IO。
网络IO优化
对于网络IO有一些基本的处理规则如下:
1。减少交互的次数。比如增加缓存,合并请求。
2。减少传输数据大小。比如压缩后传输、约定合理的数据协议。
3。减少编码。比如提前将字符转化为字节再传输。
4。根据应用场景选择合适的交互方式,同步阻塞,同步非阻塞,异步阻塞,异步非阻塞。
[/size]
发表评论
-
Java之Concurrent(并发)包
2015-09-25 16:31 284因为实在是太多了,太长了,一时间无法自习整理和消化,先 ... -
Java集合框架
2015-09-25 16:31 363集合框架有很多的 ... -
final, finally, finalize的区别
2015-09-19 11:39 3561.final final修饰类,说明 ... -
四种会话跟踪技术
2015-09-19 11:36 749会话跟踪是一种灵活、轻便的机制,它使Web上的状态编程变为可能 ... -
java中volatile关键字的含义
2015-09-19 10:59 342在java线程并发处理中, ... -
java笔记--关于线程同步(5种同步方式)
2015-09-19 10:21 386[size=medium]为何要使用同步? java ... -
RPC
2015-07-30 11:04 332RPC 功能目标 RPC 的 ... -
Java NIO原理文分析及代码实现
2015-07-22 10:43 395Java NIO原理图文分析及代码实现 前言: 最近在分 ... -
NIO学习(一)
2015-07-22 10:43 299[size=medium]NIO学习 一.NIO中的几个基础 ... -
Java IO浅谈
2015-07-21 13:12 274Java IO浅谈 [size=large] ... -
线程池(二)
2015-07-21 12:29 328Java ... -
线程池(一)
2015-07-21 12:11 333线程池 在上一篇博客中,我们有提及阻塞IO的为每个连接请求 ... -
阻塞与非阻塞-----同步与异步
2015-07-21 11:31 452阻塞(blocking)与非阻塞(non-blocking)I ...
相关推荐
该文件是基于JavaSE知识实现的简单考试系统,未使用数据库知识,底层用文件存储用户信息,初步采用MVC 分层架构思想,还包含多种设计模式。
3. 美观的界面和阅读模式:Raindrop.io_v5.6.11插件拥有简洁、美观的界面设计,使得用户能够以直观的方式浏览和搜索书签。此外,插件还提供了阅读模式,可以消除页面中的广告和分散注意力的元素,使用户专注于内容。...
可以通过实现多个Comparator接口来达到多种排序的目的. 2.装饰着模式(Decorator): 动态的给一个对象添加一些额外的职责. 比如java.io包. BufferedInputStream封装了FileInputStream, 它们都实现了InputStream接口, ...
多种IO同时并发,全局异步统一调度 支持以顺序、自然的同步风格书写异步、并发的代码逻辑 已支持MySQL、curl两大主要IO场景,理论上可支持任意类型IO的并发执行 3. 极简高效的代码运行组织机制 设计良好的 MVC 机制...
- 后端: 采用Java语言,遵循MVC设计模式,实现业务逻辑 - 数据库: 使用MySQL或其他数据库存储电影、影厅、座位以及订单信息 2. 主要功能模块 - 影片管理: 管理员可以添加、修改、删除影片信息,如电影名称、上映...
1. 培训内容设计:包括Java编程语言基础、面向对象编程、集合框架、多线程编程、IO与NIO、网络编程、数据库编程、Spring框架、设计模式等诸多模块,需要根据学员的学科背景和研究方向进行合理的内容设计。...
方法,网络编程,Tomcat,Http,Maven,Mvc三层架构,Servlet,Cookie/Session,Web,Filter,监听器,MyBatis,SpringMVC,Redis,微服务开发,SSM框架,JavaWeb,JavaSE,中间件,运维,源码探究,设计模式,以及等多种应用题...
系统设计人员在创建架构时不仅需考虑三网合一模式这一高端需求,还需满足以下要求:高性能、低延迟、较低的系统成本(包括NRE)、可扩展、可延伸架构、集成现成(OTS)组件、分布式处理、支持多种标准和协议。...
可用性迭代设计方法设计模式和可用性测试(用户体验工作组) 互操作性HTML5 -first 方法(利用原生 HTML5 支持并用“polyfills”填补支持空白) 支持多种浏览器(IE、Firefox、Chrome、Safari、Opera) 建立对 HTML ...
-由load.css和transition.css提供支持的可自定义,可动画制作的Loading.io模式库。 -将您的文本转换为GIF / SVG动画。 您可以在找到有关动画生成的更多信息。 用法 下载并包含 : <link rel="stylesheet" ...
2.3原理框图如图1.1所示—————————— 2.4设计电路的工作原理—————————————————————— 用C语言程序控制单片机最小系统,使IO口输出高低电平控制彩灯电路的闪烁。 2.5彩灯的电路工作...
4、多种控制模式,并口控制模式、串口模式、AD 按键控制模式 5、Microusb 接口更新语音文件,无需安装任何软件。支持XP 和WIN7 系统。 6、支持组合播放功能,可以实现报时、报温度,在一定程度上可以替代一些昂贵的...
制器(HMEMC)、模数转换模块(ADC)等硬核资源,支持多种配置模式,同时提供位流加 密、器件ID(UID)等功能以保护用户的设计安全。基于以上特点,Logos系列FPGA能够广泛 适用于视频、工业控制、汽车电子和消费电子...
内容:8155或8255扩展用8155或8255扩展IO实现16个LED的跑马灯,提供多种跑马 灯运行模式 二、 问题分析、方案的提出、设计思路及原因; 本次课程设计的题目是8255的扩展,利用AT89C52驱动扩展8255数据输出口来实现16...
Java面向对象 面向对象特性:封装、继承、多态等,面向对象程序设计,基础设计模式等。 掌握面向对象的基本原则以及在编程实践中的意义;掌握Java面向对象编程基本实现原理。 实训项目一:Tetris项目开发 第二阶段...
4.21 用带SPI接口的MCP23S17扩展16位通用IO端口 4.22 用TWI接口控制MAX6953驱动4片5×7点阵显示器 4.23 用TWI接口控制MAX6955驱动16段数码管显示 4.24 用DAC0832生成多种波形 4.25 用带SPI接口的数模转换芯片MAX...
4.21 用带SPI接口的MCP23S17扩展16位通用IO端口 4.22 用TWI接口控制MAX6953驱动4片5×7点阵显示器 4.23 用TWI接口控制MAX6955驱动16段数码管显示 4.24 用DAC0832生成多种波形 4.25 用带SPI接口的数模转换芯片MAX...
《单片机》课程设计 课程设计题目 出租车计价器 专 业:计算机控制 班 级:控制09--3 姓 名:费翔 学 号:20 指导教师:范爱华 2012年3月2日 "设计题目:出租车计价器 " "设计目的: " "利用单片机丰富的IO端口,...
基于单片机的电子日历设计 一、设计目的和要求 ... IO口是否满足系统设计要求:51有32个IO口,msp430的IO口则更多。这一点都满足 要求。 是否需要外加时钟芯片:采用定时器,误差较大。Msp430内部就有时钟RTC单元, 5
在我们的研究工作中,我们为并行 I/O 系统设计并开发了多种性能优化技术。 许多技术是应用程序感知的,可以利用应用程序的 I/O 特性信息来提高 I/O 系统的效率。 我们使用 IOSIG 来收集和分析应用程序的 I/O 特性,...