今天我们以一个常见的面试题作为开始:"谈谈你对IO与NIO的理解"。要回答这个问题,我们首先我要了解几个概念:

NIO 同步+非阻塞

IO(BIO) 同步+阻塞

AIO 异步+非阻塞

阻塞与非阻塞:

阻塞概念:应用程序在获取网络数据的时候,如果网络传输数据很慢,那么程序就一直等着,直到传输完毕为止;

非阻塞概念:应用程序直接获取已准备好的数据,无需等待。

IO为同步阻塞形式,NIO为同步非阻塞形式。NIO并没有实现异步,在JDK1.7后升级了NIO库包,支持异步非阻塞通信模型即NIO2.0(AIO)

同步和异步:

同步和异步一般是面向操作系统与应用程序对IO操作的层面上来区别的:

同步时:应用程序会直接参与IO读写操作,并且我们的应用程序会直接阻塞到某一个方法上,知道数据准备就绪:或者采用轮询的策略实时检查数据的就绪状态,如果就绪则获取数据。

异步时:则所有的IO读写操作交给操作系统处理,与我们应用程序没有直接关系,我们的程序不需要关心IO读写,当操作系统完成了IO读写操作时,会给我们的应用程序发送通知,我们的应用程序直接拿走数据即可。

同步说的是你的Server服务器端的执行方式 ;阻塞说的是具体的技术,接受数据的方式、状态(io,nio)。

NIO

  • Buffer(缓冲区)

    Buffer是一个对象,它包含一些要写入或者读取的数据。在NIO类库中加入Buffer对象,提现了新库与原IO的一个重要区别。在面向流的IO中,可以将数据直接写入或读取到Stream对象中。在NIO库中,所有数据都是用缓冲区处理的(读写)。缓冲区实质上是一个数组,它通常是一个字节数组(ByteBuffer),也可以使用其他类型的数组。这个数组为缓冲区提供了数据的访问读写等操作属性,如位置、容量、上限等概念。

    Buffer类型:ByteBuffer、CharBuffer、ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer

  • Channel(管道、通道)

    通道Channel它就像自来水管一样,网络数据通过Channel读取和写入,通道与留不同之处在于通道是双向的,而流只是在一个方向上移动(一个流必须是InputStream或者OutPutStream的子类),而通道可以用于读、写或者2者同时进行,最关键的是可以与多路复合器结合起来,有多种的状态位,方便多路复用器去识别。

    事实上通道分为两大类,一类是网络读写的(SelectableChannel),一类用于文件操作的(FileChannel),我们使用SocketChannel和ServerChannel都是SelectableChannel的子类。

  • Selector(选择器、多路复用器)

    多路复用器是NIO编程的基础,非常重要。Selector提供选择已经就绪的任务的能力。

    简单说就是Selector会不断的轮询注册在其上的通道Channel,如果某个通道发生了读写操作,这个通道就处于就绪状态,会被Selector轮询出来,然后通过Selectionkey可以取得就绪的Channel集合,从而进行后续的IO操作。

    一个多路复用器可以负责成千上万个Channel通道,没有上限,这也是JDK使用了epoll代替了传统的select实现,获得连接句柄没有限制。这样意味着我们只要一个线程负责Selector的轮询,就可以接入成千上万个客户端,这是JDK NIO 的巨大进步。

    Selector线程就类似一个管理者Master,管理成千上万个Channel,然后轮询哪个管道的数据已经准备好,通知CPU执行IO的读取或写入操作。

    Selector模式:当IO事件(管道)注册到选择器后,Selector会分配给每个管道一个key值,相当于标签。Selector选择器是以轮询的方式进行查找注册所有的IO事件。当我们的IO事件(管道)准备就绪后,select就会识别,会通过key值找到相应的管道,进行相关的数据处理操作(从管道里读或写数据,写到我们的数据缓冲区Buffer去)

    每个管道都会对选择器进行注册到不同的事件状态,以便选择器查找:

    SelectionKey.OP_CONNECT    SelectionKey.OP_ACCEPT    SelectionKey.OP_READ    SelectionKey.OP_WRITE

如上图所示:

比如我们这有一个Server端,N个Client,在古老编程中是由Client发送套接字至Server端建立tcp的连接,然后两端进行通信;NIO是在传统点对点直连基础之上做了一层抽象,Client端要与Service端建立连接,Service端会建立一个Selector多路复用器,客户端使用SocketChannel注册到Selector,Selector轮询所有注册的通道,根据通道状态执行相关操作。

AIO

AIO编程在NIO基础上引入了异步通道的概念,并提供了异步文件和异步套接字通道的实现,从而在真正意义上实现了异步非阻塞,之前我们学习的NIO只是非阻塞而非异步,而AIO它不需要通过多路复用器对注册的通道进行轮询操作即可实现异步读写,从而简化了NIO编程模型,也可以称之为NIO2.0,这种模式才真正属于我们异步非阻塞的模型。

AsynchronousServerSocketChannel

AsynchronousSocketChannel

 

NIO、AIO学习历程的更多相关文章

  1. java BIO/NIO/AIO 学习

    一.了解Unix网络编程5种I/O模型 1.1.阻塞式I/O模型 阻塞I/O(blocking I/O)模型,进程调用recvfrom,其系统调用直到数据报到达且被拷贝到应用进程的缓冲区中或者发生错误 ...

  2. bio,nio,aio学习

    http://qindongliang.iteye.com/blog/2018539 1 同步 指的是用户进程触发IO操作并等待或者轮询的去查看IO操作是否就绪 自己上街买衣服,自己亲自干这件事,别的 ...

  3. I/O模型系列之三:IO通信模型BIO NIO AIO

    一.传统的BIO 网络编程的基本模型是Client/Server模型,也就是两个进程之间进行相互通信,其中服务端提供位置信息(绑定的IP地址和监听端口),客户端通过连接操作向服务端监听的地址发起连接请 ...

  4. IO回忆录之怎样过目不忘(BIO/NIO/AIO/Netty)

    有热心的网友加我微信,时不时问我一些技术的或者学习技术的问题.有时候我回微信的时候都是半夜了.但是我很乐意解答他们的问题.因为这些年轻人都是很有上进心的,所以在我心里他们就是很优秀的,我愿意多和努力的 ...

  5. Netty5序章之BIO NIO AIO演变

    Netty5序章之BIO NIO AIO演变 Netty是一个提供异步事件驱动的网络应用框架,用以快速开发高性能.高可靠的网络服务器和客户端程序.Netty简化了网络程序的开发,是很多框架和公司都在使 ...

  6. Netty序章之BIO NIO AIO演变

    Netty序章之BIO NIO AIO演变 Netty是一个提供异步事件驱动的网络应用框架,用以快速开发高性能.高可靠的网络服务器和客户端程序.Netty简化了网络程序的开发,是很多框架和公司都在使用 ...

  7. BIO,NIO,AIO总结

    熟练掌握 BIO,NIO,AIO 的基本概念以及一些常见问题是你准备面试的过程中不可或缺的一部分,另外这些知识点也是你学习 Netty 的基础. BIO,NIO,AIO 总结 1. BIO (Bloc ...

  8. 3. 彤哥说netty系列之Java BIO NIO AIO进化史

    你好,我是彤哥,本篇是netty系列的第三篇. 欢迎来我的公从号彤哥读源码系统地学习源码&架构的知识. 简介 上一章我们介绍了IO的五种模型,实际上Java只支持其中的三种,即BIO/NIO/ ...

  9. (转)也谈BIO | NIO | AIO (Java版)

    原文地址: https://my.oschina.net/bluesky0leon/blog/132361 关于BIO | NIO | AIO的讨论一直存在,有时候也很容易让人混淆,就我的理解,给出一 ...

随机推荐

  1. 获取PHP页面的当前文件名(包括后缀名)

    // $curPhp = substr($_SERVER['PHP_SELF'],strripos($_SERVER['PHP_SELF'],'/')+1); // print_r($_SERVER[ ...

  2. stark组件前戏(2)之单例模式

    单,一个. 例,实例.对象. 通过利用Python模块导入的特性:在Python中,如果已经导入过的文件再被重新导入时候,python不会重新解释一遍,而是选择从内容中直接将原来导入的值拿来用.   ...

  3. CSAPP 缓冲区溢出试验

    缓冲区溢出试验是CSAPP课后试验之一,目的是: 更好的理解什么是缓冲区溢出 如何攻击带有缓冲区溢出漏洞的程序 如何编写出更加安全的代码 了解并理解编译器和操作系统为了让程序更加安全而提供的几种特性 ...

  4. 【Todo】 cygwin下emacs中M-x shell 中出现乱码

  5. Flask With

  6. leetcode 【 Subsets 】python 实现

    题目: Given a set of distinct integers, S, return all possible subsets. Note: Elements in a subset mus ...

  7. Python基础-week02 Python的常用数据类型

    一.模块初识 import导入Py自带模块例如os,sys等及其自己编写的Py文件,导入到其他文件中,默认查找当前目录.如果不在同一目录,会报错,将该自定义py文件模块放到site-packages目 ...

  8. 查看sqlserver表空间

    exec sp_msforeachtable "exec sp_spaceused '?'"

  9. leetcode NO.171 Excel表列序号 (python实现)

    来源 https://leetcode-cn.com/problems/excel-sheet-column-number/description/ 题目描述 给定一个Excel表格中的列名称,返回其 ...

  10. Unity --yield return

    1.yield return null; //暂停协同程序,下一帧再继续往下执行 yield new WaitForFixedUpdate (); //暂停协同程序,等到下一次调用FixedUpdat ...