转载:BIO | NIO | AIO
http://my.oschina.net/bluesky0leon/blog/132361
关于BIO | NIO | AIO的讨论一直存在,有时候也很容易让人混淆,就我的理解,给出一个解释:
BIO | NIO | AIO,本身的描述都是在Java语言的基础上的。而描述IO,我们需要从两个层面:
- 编程语言
- 实现原理
- 底层基础
从编程语言层面
BIO | NIO | AIO 以Java的角度,理解,linux c里也有AIO的概念(库),这些概念不知道什么原因被炒火起来,这里只从Java角度入手。
- BIO,同步阻塞式IO,简单理解:一个连接一个线程
- NIO,同步非阻塞IO,简单理解:一个请求一个线程
- AIO,异步非阻塞IO,简单理解:一个有效请求一个线程
BIO
在JDK1.4之前,用Java编写网络请求,都是建立一个ServerSocket,然后,客户端建立Socket时就会询问是否有线程可以处理,如果没有,要么等待,要么被拒绝。即:一个连接,要求Server对应一个处理线程。
NIO
在Java里的由来,在JDK1.4及以后版本中提供了一套API来专门操作非阻塞I/O,我们可以在java.nio包及其子包中找到相关的类和接口。由于这套API是JDK新提供的I/O API,因此,也叫New I/O,这就是包名nio的由来。这套API由三个主要的部分组成:缓冲区(Buffers)、通道(Channels)和非阻塞I/O的核心类组成。在理解NIO的时候,需要区分,说的是New I/O还是非阻塞IO,New I/O是Java的包,NIO是非阻塞IO概念。这里讲的是后面一种。
NIO本身是基于事件驱动思想来完成的,其主要想解决的是BIO的大并发问题: 在使用同步I/O的网络应用中,如果要同时处理多个客户端请求,或是在客户端要同时和多个服务器进行通讯,就必须使用多线程来处理。也就是说,将每一个客户端请求分配给一个线程来单独处理。这样做虽然可以达到我们的要求,但同时又会带来另外一个问题。由于每创建一个线程,就要为这个线程分配一定的内存空间(也叫工作存储器),而且操作系统本身也对线程的总数有一定的限制。如果客户端的请求过多,服务端程序可能会因为不堪重负而拒绝客户端的请求,甚至服务器可能会因此而瘫痪。
NIO基于Reactor,当socket有流可读或可写入socket时,操作系统会相应的通知引用程序进行处理,应用再将流读取到缓冲区或写入操作系统。 也就是说,这个时候,已经不是一个连接就要对应一个处理线程了,而是有效的请求,对应一个线程,当连接没有数据时,是没有工作线程来处理的。
AIO
与NIO不同,当进行读写操作时,只须直接调用API的read或write方法即可。这两种方法均为异步的,对于读操作而言,当有流可读取时,操作系统会将可读的流传入read方法的缓冲区,并通知应用程序;对于写操作而言,当操作系统将write方法传递的流写入完毕时,操作系统主动通知应用程序。 即可以理解为,read/write方法都是异步的,完成后会主动调用回调函数。 在JDK1.7中,这部分内容被称作NIO.2,主要在java.nio.channels包下增加了下面四个异步通道:
- AsynchronousSocketChannel
- AsynchronousServerSocketChannel
- AsynchronousFileChannel
- AsynchronousDatagramChannel
其中的read/write方法,会返回一个带回调函数的对象,当执行完读取/写入操作后,直接调用回调函数。
实现原理
说道实现原理,还要从操作系统的IO模型上了解
按照《Unix网络编程》的划分,IO模型可以分为:阻塞IO、非阻塞IO、IO复用、信号驱动IO和异步IO,按照POSIX标准来划分只分为两类:同步IO和异步IO。如何区分呢?首先一个IO操作其实分成了两个步骤:发起IO请求和实际的IO操作,同步IO和异步IO的区别就在于第二个步骤是否阻塞,如果实际的IO读写阻塞请求进程,那么就是同步IO,因此阻塞IO、非阻塞IO、IO复用、信号驱动IO都是同步IO,如果不阻塞,而是操作系统帮你做完IO操作再将结果返回给你,那么就是异步IO。阻塞IO和非阻塞IO的区别在于第一步,发起IO请求是否会被阻塞,如果阻塞直到完成那么就是传统的阻塞IO,如果不阻塞,那么就是非阻塞IO。
收到操作系统的IO模型,又不得不提select/poll/epoll/iocp,关于这四个的理解,不多做解释,自己还没理解到位。
可以理解的说明是:在Linux 2.6以后,java NIO的实现,是通过epoll来实现的,这点可以通过jdk的源代码发现。而AIO,在windows上是通过IOCP实现的,在linux上还是通过epoll来实现的。
这里强调一点:AIO,这是I/O处理模式,而epoll等都是实现AIO的一种编程模型;换句话说,AIO是一种接口标准,各家操作系统可以实现也可以不实现。在不同操作系统上在高并发情况下最好都采用操作系统推荐的方式。Linux上还没有真正实现网络方式的AIO。
底层基础
说到底层,要说Linux系统编程,这里自己也不熟悉,有待后来人补充了。 只笼统的说一个:AIO实现
在windows上,AIO的实现是通过IOCP来完成的,看JDK的源代码,可以发现
WindowsAsynchronousSocketChannelImpl
看实现接口:
implements Iocp.OverlappedChannel
再看实现方法:里面的read0/write0方法是native方法,调用的jvm底层实现,虚拟机技术不熟悉,不献丑了。
在linux上,AIO的实现是通过epoll来完成的,看JDK源码,可以发现,实现源码是:
UnixAsynchronousSocketChannelImpl
看实现接口:
implements Port.PollableChannel
这是与windows最大的区别,poll的实现,在linux2.6后,默认使用epoll。
这样就可以理解了。
写在最后:Java开发为基础的,对于操作系统底层的认知是没有C语言为基础的大牛好的,语言决定了思维方式,古人诚不欺我
最后,几篇解释的不错的文章:
转载:BIO | NIO | AIO的更多相关文章
- [转]BIO/NIO/AIO的几个思考
原文:https://www.jianshu.com/p/ff29e028af07 ----------------------------------------------------- BIO/ ...
- (转)也谈BIO | NIO | AIO (Java版)
原文地址: https://my.oschina.net/bluesky0leon/blog/132361 关于BIO | NIO | AIO的讨论一直存在,有时候也很容易让人混淆,就我的理解,给出一 ...
- 拿搬东西来解释udp tcpip bio nio aio aio异步
[群主]雷欧纳德简单理解 tcpip是有通信确认的面对面通信 有打招呼的过程 有建立通道的过程 有保持通道的确认 有具体传输udp是看到对面的人好像在对面等你 就往对面扔东西[群主]雷欧 ...
- 也谈BIO | NIO | AIO (Java版--转)
关于BIO | NIO | AIO的讨论一直存在,有时候也很容易让人混淆,就我的理解,给出一个解释: BIO | NIO | AIO,本身的描述都是在Java语言的基础上的.而描述IO,我们需要从两个 ...
- IO回忆录之怎样过目不忘(BIO/NIO/AIO/Netty)
有热心的网友加我微信,时不时问我一些技术的或者学习技术的问题.有时候我回微信的时候都是半夜了.但是我很乐意解答他们的问题.因为这些年轻人都是很有上进心的,所以在我心里他们就是很优秀的,我愿意多和努力的 ...
- Netty5序章之BIO NIO AIO演变
Netty5序章之BIO NIO AIO演变 Netty是一个提供异步事件驱动的网络应用框架,用以快速开发高性能.高可靠的网络服务器和客户端程序.Netty简化了网络程序的开发,是很多框架和公司都在使 ...
- I/O模型系列之三:IO通信模型BIO NIO AIO
一.传统的BIO 网络编程的基本模型是Client/Server模型,也就是两个进程之间进行相互通信,其中服务端提供位置信息(绑定的IP地址和监听端口),客户端通过连接操作向服务端监听的地址发起连接请 ...
- 【netty】(1)---BIO NIO AIO演变
BIO NIO AIO演变 Netty是一个提供异步事件驱动的网络应用框架,用以快速开发高性能.高可靠的网络服务器和客户端程序.Netty简化了网络程序的开发,是很多框架和公司都在使用的技术. Net ...
- Netty序章之BIO NIO AIO演变
Netty序章之BIO NIO AIO演变 Netty是一个提供异步事件驱动的网络应用框架,用以快速开发高性能.高可靠的网络服务器和客户端程序.Netty简化了网络程序的开发,是很多框架和公司都在使用 ...
随机推荐
- Jenkins Pipeline+sonar构建质量平台
前提: Jenkins JDK 目录: 1.安装sonar插件:SonarQube Scanner for Jenkins 2.安装SonarQube 3.安装sonar-scanner ++++++ ...
- Android 内存管理研究
1. 内存管理基础知识 http://www.cnblogs.com/xingfuzzhd/p/3485924.html 1. mImageView.setImageResource(R.drawab ...
- html基础整理(02浮动 问题)
margin的塌陷现象及解决方案 如果一个大盒子中包含一个小盒子,给小盒子设置margin-top,大盒子会一起向下平移 - 解决方案: 1. 给大盒子加一个边框(border) 2. 给大盒子 ...
- css编写规范最佳实践
最初,在编写CSS的时候,我们往往想到哪儿就写到哪儿,它们之间的关联性和有序性并不在考虑之中.但随着代码量的增加,亦或是多人共同开发,CSS的编写规范变得重要起来了.本文通过三个方面,总结出CSS编写 ...
- CentOS7打开关闭防火墙与端口
http://www.javahelp.com.cn/h-nd-747.html#_np=153_1707
- Mutation Observer
MutationEvent Mutation Observer 变动观察器, 等待所有脚本任务完成后,才会运行(即异步触发方式) 把DOM变动记录封装成一个数组进行处理,而不是一条条个别处理DOM变动 ...
- 【JavaScript】动态原型模式创建对象 ||为何不能用字面量创建原型对象?
var proto = ""; function Person(name, age, job) { this.name = name; this.age = age; this.j ...
- jquery text html width heigth的用法
<body> <div id="div1"> <h3>我是标题</h3> </div> <div id=" ...
- python 全栈开发:基础复习
格式化输出: username = 'python' password = 'python1' print(''' username:%s password:%s '''%(username,pass ...
- mysql.sock文件丢失被删除解决方法
Mysql有两种连接方式: (1),TCP/IP (2),socket 对mysql.sock来说,其作用是程序与mysqlserver处于同一台机器,发起本地连接时可用. 例如你无须定义连接host ...