BIO,NIO,AIO

转载 2016年08月30日 19:35:53

关于BIO | NIO | AIO的讨论一直存在,有时候也很容易让人混淆,就我的理解,给出一个解释:

BIO | NIO | AIO,本身的描述都是在Java语言的基础上的。而描述IO,我们需要从两个层面:

  1. 编程语言
  2. 实现原理
  3. 底层基础

从编程语言层面

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

NIO.2 入门,第 1 部分: 异步通道 API

使用异步 I/O 大大提高应用程序的性能

BIO与NIO、AIO的区别(这个容易理解)

IO的方式通常分为几种,同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO。 一、BIO      在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一...
  • skiof007
  • skiof007
  • 2016年10月20日 15:52
  • 38579

Java 网络IO编程总结(BIO、NIO、AIO均含完整实例代码)

本文会从传统的BIO到NIO再到AIO自浅至深介绍,并附上完整的代码讲解。 1、BIO编程 1.1、传统的BIO编程 网络编程的基本模型是C/S模型,即两个进程间的通信。 服务...
  • anxpp
  • anxpp
  • 2016年05月29日 01:46
  • 90734

NIo、Bio、aio、 的原理及区别与应用场景

在高性能的IO体系设计中,有几个名词概念常常会使我们感到迷惑不解。具体如下:  序号 问题 1 什么是同步? 2 什么是异步? 3 什么是阻塞?...
  • u013851082
  • u013851082
  • 2016年12月30日 14:47
  • 5596

BIO,NIO,AIO的区别

一、看图 网上很多IO资料,对新手来说,越看越晕。根据自己的理解,总结对比了一下BIO、NIO、AIO。 BIO:线程发起IO请求,不管内核是否准备好IO操作,从发起请求起,线程一直阻塞,直到操作...
  • u013068377
  • u013068377
  • 2017年04月21日 11:00
  • 1210

Java中BIO,NIO和AIO使用样例

转自:http://blog.insanecoder.top/javazhong-bio-niohe-aioshi-yong-yang-li/ 上文中分析了阻塞,非阻塞,同步和异步概念上的区别以...
  • Scythe666
  • Scythe666
  • 2016年07月21日 12:58
  • 1373

【NIO引入】BIO、AIO与NIO的区别

同步异步与阻塞非阻塞的区别1.同步例:买饭:自己亲自去饭馆买饭,这就是同步(自己处理IO读写)2.异步例:买饭:叫外卖送到家,这就是异步(IO读写委托给OS处理,需要将数据缓冲区地址和大小传给OS(饭...
  • baiye_xing
  • baiye_xing
  • 2017年06月12日 16:29
  • 1644

JAVA 中BIO,NIO,AIO的理解

在高性能的IO体系设计中,有几个名词概念常常会使我们感到迷惑不解。具体如下:  序号 问题 1 什么是同步? 2 什么是异步? 3 什么是阻塞? 4 什么是非阻塞? 5 什...
  • chengzhezhijian
  • chengzhezhijian
  • 2015年01月30日 13:56
  • 1756

java NIO、BIO、AIO区别

java中的IO主要源自于网络和本地文件        IO的方式通常分为几种,同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO      在JDK1.4出来之前,我们建立网...
  • liuxiao723846
  • liuxiao723846
  • 2015年04月15日 22:35
  • 4545

BIO、NIO、AIO区别

网上很多IO资料,对新手来说,越看越晕。根据自己的理解,总结对比了一下OIO、NIO、AIO。 OIO:线程发起IO请求,不管内核是否准备好IO操作,从发起请求起,线程一直阻塞,直到操作完成。如下图:...
  • wodeyuer125
  • wodeyuer125
  • 2014年05月22日 12:19
  • 2929

面试知识点3:JAVA中的BIO、NIO和AIO

Java中的IO方式主要分为3种:BIO(同步阻塞)、NIO(同步非阻塞)和AIO(异步非阻塞)。 BIO 同步阻塞模式。在JDK1.4以前,使用Java建立网络连接时,只能采用BIO方式,在服务器端...
  • RoxLiu
  • RoxLiu
  • 2014年11月13日 18:25
  • 1036
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:BIO,NIO,AIO
举报原因:
原因补充:

(最多只允许输入30个字)