NIO&AIO编程模型
NIO线程模型

什么是NIO线程模型?
上图是NIO的线程模型, 基于select实现, 这种线程模型的特点: 多条channel通过一个选择器和单挑线程绑定, 并且在这种编程模型中, Channel中相关业务逻辑不允许存在耗时的任务 , 如果一定会有耗时的逻辑, 请将它们放置到线程池中去运行, 因为这种模型虽然做到了非阻塞, 但是他并不是真正的异步编程, 任何channel上的任何耗时的操作, 都会拖垮这个选择器, 进而拖垮整条线程 , 这也是为啥它会被称为 同步非阻塞
什么是同步?
- 其一: 因为当channel中出现了耗时的操作时, 其他的channel不得不同步等待
- 其二: 从编码上看: NIO编程中 服务端的
select()会同步等待选择器感兴趣的事件发生 - 其三: 从操作系统的角度上看, 程序使用的数据来自 网卡 -> 操作系统的内核缓冲区 -> 用户区, 当数据进入用户区后java程序便可以对其进行读写操作, 所谓同步就是: 数据进入用户区的过程中,NIO编程模型需要同步并不停的询问
NIO线程模型的优点
NIO线程线程模型相对于传统的BIO来说, 最大的优势就是在于 NIO线程模型中单条线程可同时为N个用户(Channel)服务, 而BIO编程模型让人诟病的地方就是, 任何一个新连接接入, 服务器都得为他开启不止一条新的线程去运行它, 这种BIO系统中, 并发肯定不会很高
NIO适用场景:
NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持
AIO (Asynchronous Input/Output )模型
什么是AIO?
AIO是(jdk1.7) 发行的 异步IO编程模型, 真正实现了异步IO, 基于Linux系统的 Epoll 机制实现
无论是NIO, 还是AIO底层都没有改变网络通信的基本步骤, 而是在这个基础上进行了一系列的升级
AIO的底层实现是由操作系统完成的, 数据在内核空间&用户空间的迁移, 我们在编写代码时也是这样, 只需要调用 AIO.read() 或者是 AIO.write() 即可, 换句话说, 我们的业务逻辑就成了 回调, 原来在操作系统处理数据的这个过程中, 我们的程序需要阻塞等待着, 亦或者放在线程池中运行, 而在AIO编程中这段等待时间差被省去了, 因为当操作系统认为数据还有没准备完时, 它是不会打扰我们的程序的, 这时我们的程序可以去处理其他的逻辑, 而一旦操作系统认为数据齐全了, 他就会回调我们的提供的回调函数
- 对应操作系统来说, 当有流数据可读时, 操作系统会将流传入到read方法的缓冲区, 然后回调相关的 CompletionHandler
- 对于写操作而言, 操作系统会将程序中Buffer里面数据写入到从用户空间写入到系统空间 再写入到网卡中, 写入完毕, 同样会回调相关的回调函数
AIO编程Server端的示例
下面贴出来一个AIO编程Server端的实例:
像下面的 read() write() accept() 全是异步的, 一经调用即刻返回, 不一样的地方是我们会提供一个回调对象, 留给操作系统, 当操作系统认为读写数据都到位了, 就会去回调这些函数
public class AIOServer {
private ExecutorService executorService;
// 服务端的Channel
private AsynchronousServerSocketChannel asynchronousServerSocketChannel;
private AIOServer(int port) {
init(port);
}
// 初始化
private void init(int port) {
System.out.println("aio server start with port " + port);
executorService = Executors.newFixedThreadPool(5);
try {
// 开启服务端的通道
asynchronousServerSocketChannel = AsynchronousServerSocketChannel.open();
// 绑定端口
asynchronousServerSocketChannel.bind(new InetSocketAddress(port));
System.out.println("server start ... ");
/**
* 方法会异步的去接收一个请求, accept()同样是
* 参数1 : this , 暂时理解成任意类型的
* 参数2 : CompleteHandler -- 当请求到来后,会交付给 AIOServerHandler进行处理
*
* todo 在 AIO中的监听并不是while(true), 而是类似递归的操作, 每次监听到客户端的请求后, 都需要在处理逻辑中开启下一次的监听
*/
asynchronousServerSocketChannel.accept(this, new AIOServerHandler());
System.out.println("------------------------------");
// 阻塞程序
try {
TimeUnit.SECONDS.sleep(60);
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public AsynchronousServerSocketChannel getAsynchronousServerSocketChannel() {
return this.asynchronousServerSocketChannel;
}
public static void main(String[] args) {
AIOServer aioServer = new AIOServer(9999);
}
}
AIO的适用场景
AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。
我是bloger 赐我白日梦, 欢迎关注我 --武汉加油
NIO&AIO编程模型的更多相关文章
- 手动搭建I/O网络通信框架4:AIO编程模型,聊天室终极改造
第一章:手动搭建I/O网络通信框架1:Socket和ServerSocket入门实战,实现单聊 第二章:手动搭建I/O网络通信框架2:BIO编程模型实现群聊 第三章:手动搭建I/O网络通信框架3:NI ...
- Java NIO系列教程(八)JDK AIO编程
目录: Reactor(反应堆)和Proactor(前摄器) <I/O模型之三:两种高性能 I/O 设计模式 Reactor 和 Proactor> <[转]第8章 前摄器(Proa ...
- io编程,bio,nio,aio
本文会从传统的BIO到NIO再到AIO自浅至深介绍,并附上完整的代码讲解. 下面代码中会使用这样一个例子:客户端发送一段算式的字符串到服务器,服务器计算后返回结果到客户端. 代码的所有说明,都直接作为 ...
- 手动搭建I/O网络通信框架3:NIO编程模型,升级改造聊天室
第一章:手动搭建I/O网络通信框架1:Socket和ServerSocket入门实战,实现单聊 第二章:手动搭建I/O网络通信框架2:BIO编程模型实现群聊 在第二章中用BIO编程模型,简单的实现了一 ...
- 谈谈传统BIO网络编程模型的局限性与NIO
先来看看我们的server端: 创建一个serversocket,进行监听,每来一个客户端,就启动一个新启动为其服务: private void createListenSocket() { //如果 ...
- Nio编程模型总结
终于,这两天的考试熬过去了, 兴致冲冲的来整理笔记来, 这篇博客是我近几天的NIO印象笔记汇总,记录了对Selector及Selector的重要参数的理解,对Channel的理解,常见的Channel ...
- JDK AIO编程
NIO2.0引入了新的异步通道的概念,并提供了异步文件通道和异步套接字通道的实现.异步通道提供两种方式获取获取操作结果. 通过java.util.concurrent.Future类来表示异步操作的结 ...
- Java IO编程全解(五)——AIO编程
转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/7794151.html 前面讲到:Java IO编程全解(四)--NIO编程 NIO2.0引入了新的异步通道的 ...
- 深入学习Netty(3)——传统AIO编程
前言 之前已经整理过了BIO.NIO两种I/O的相关博文,每一种I/O都有其特点,但相对开发而言,肯定是要又高效又简单的I/O编程才是真正需要的,在之前的NIO博文(深入学习Netty(2)--传统N ...
随机推荐
- D3.js力导向图中新增节点及新增关系连线示例
大家在使用D3.js中的力导向图时,基本都会遇到动态增加节点及连线的需求,这里记录一下我的实现方式. 话不多说,先放代码: <!DOCTYPE html> <html lang=&q ...
- H3C网络监测工具命令
1.Debugging 2.Display debugging 3.Display diagnostic-information display diagnostic-information 命令用来 ...
- egg-socket在egg中的使用
WebSocket 的产生源于 Web 开发中日益增长的实时通信需求,对比基于 http 的轮询方式,它大大节省了网络带宽,同时也降低了服务器的性能消耗: socket.io 支持 websocket ...
- MFC下获取系统内存和当前进程的内存使用情况
GlobalMemoryStatusEx来获取系统的内存使用情况 GetProcessMemoryInfo获取某个进程的内存使用情况.和任务管理器看到的是一样的. 具体代码如下: void GetSy ...
- dotnet 新项目格式与对应框架预定义的宏
在 sdk style 的项目格式支持使用多框架开发,此时需要在代码里面通过宏判断,在编译的时候执行不同的代码.本文告诉大家在框架里面对应的预定义的条件编译符有哪些 在让一个 csproj 项目指定多 ...
- HDU6578 2019HDU多校训练赛第一场 1001 (dp)
HDU6578 2019HDU多校训练赛第一场 1001 (dp) 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6578 题意: 你有n个空需要去填,有 ...
- Dubbo-本地Bean测试
Dubbo本地测试API的Bean 一.建立一个测试类文件 二.测试API // 自己要测试的API public static final XxApi xxApi; 三.注入Bean static ...
- docker 使用elasticsearch+logstash
1.1部署elasticsearch:6.5.4 docker pull elasticsearch:6.5.4 docker run -d --name elasticsearch -p 9200: ...
- 最全最详细的PHP面试题(带有答案)
这篇文章介绍的内容是关于最全最详细的PHP面试题(带有答案),有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 相关推荐: 分享一波腾讯PHP面试题 2019年PHP最新面试题(含答案) ...
- 工厂设计模式灵魂拷问-Java实现
show me the code and take to me,做的出来更要说的明白 GitHub项目JavaHouse同步收录 喜欢就点个赞呗! 你的支持是我分享的动力! 引入 我们经常听到工厂模式 ...