早上复习了IO、NIO、AIO相关的概念,将其中一些要点记录一下。

从编程语言层面

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。

https://my.oschina.net/bluesky0leon/blog/132361

IO一般发生在读写硬盘或网络文件,涉及到多个部分的请求调用,简单说是对请求调用双方的处理情况。阻塞非阻塞就是指请求调用时请求方是否释放cpu资源一直等结果,若是请求方就被阻赛,否则为非阻赛。而异步同步是指被请求方是否会同步返回结果,还是先告知已接受到请求,处理完请求后将结果告知请求方。

BIO可看作一个连接一个线程,而NIO、AIO是一个有限请求一个连接。

io最老
nio是1.4的特性
aio是1.7的特性
io是面向流的,是就用多少拿多少。是阻塞的。数据量不大的或者不在意阻塞的时可以用。
nio是面向块的,先把数据搬过来,先存到缓存区里面,如果线程要用从缓存区拿。所以线程不需要时刻盯着io了,可以先做一些其他的事情,过几天再来看一下缓存。是同步非阻塞的。因此,nio里有Buffer类作为缓冲区,Channel(通道)相当于io里的steam的抽象,Selector是nio提供的管理多个Channel的工具。nio出现也是因为io渐渐成为一些程序速度的瓶颈。
aio加了一个异步的特性。当我们要拿数据花费时间太长的时候,我们可以考虑使用异步的io。异步就是可以理解为,让io先处理者,我线程先去干别的事情了,你io处理完了通知我一下。aio提供的事件处理接口CompletionHandler,定义了回调函数,这些函数再io完成后会被自动的调用。

作者:rail gun
链接:https://www.zhihu.com/question/40930889/answer/146567853

Java IO 基础的更多相关文章

  1. java IO基础操作

    java IO基础,通熟易懂,好久没复习java 基础了.这里是传送门... http://www.cnblogs.com/nerxious/archive/2012/12/15/2818848.ht ...

  2. 归纳从文件中读取数据的六种方法-JAVA IO基础总结第2篇

    在上一篇文章中,我为大家介绍了<5种创建文件并写入文件数据的方法>,本节我们为大家来介绍6种从文件中读取数据的方法. 另外为了方便大家理解,我为这一篇文章录制了对应的视频:总结java从文 ...

  3. 总结java创建文件夹的4种方法及其优缺点-JAVA IO基础总结第三篇

    本文是Java IO总结系列篇的第3篇,前篇的访问地址如下: 总结java中创建并写文件的5种方式-JAVA IO基础总结第一篇 总结java从文件中读取数据的6种方法-JAVA IO基础总结第二篇 ...

  4. 总结删除文件或文件夹的7种方法-JAVA IO基础总结第4篇

    本文是Java IO总结系列篇的第4篇,前篇的访问地址如下: 总结java中创建并写文件的5种方式-JAVA IO基础总结第一篇 总结java从文件中读取数据的6种方法-JAVA IO基础总结第二篇 ...

  5. 总结java中文件拷贝剪切的5种方式-JAVA IO基础总结第五篇

    本文是Java IO总结系列篇的第5篇,前篇的访问地址如下: 总结java中创建并写文件的5种方式-JAVA IO基础总结第一篇 总结java从文件中读取数据的6种方法-JAVA IO基础总结第二篇 ...

  6. Java io基础

    1.什么是IO? Java IO即Java 输入输出系统.不管我们编写何种应用,都难免和各种输入输出相关的媒介打交道,其实和媒介进行IO的过程是十分复杂的,这要考虑的因素特别多,比如我们要考虑和哪种媒 ...

  7. Java IO基础--File常用操作(递归)

    File中经常会使用递归方法打印属性结构.统计文件夹下文件个数.子文件夹个数以及文件大小,可以作为递归的应用练习. 递归的写法,百度一搜一大堆,这里我使用对javabean方式封装了一下: packa ...

  8. java io基础(java.io)

    首先流分为输入和输出流,java分为字节流和字符流 1.字节输入流io.InputStream io.InputStream是一个抽象类它实现了Closeable接口的抽象类.那么它的子类(io包下) ...

  9. Java IO基础总结

    Java中使用IO(输入输出)来读取和写入,读写设备上的数据.硬盘文件.内存.键盘......,根据数据的走向可分为输入流和输出流,这个走向是以内存为基准的,即往内存中读数据是输入流,从内存中往外写是 ...

  10. 【转载】Java IO基础总结

    Java中使用IO(输入输出)来读取和写入,读写设备上的数据.硬盘文件.内存.键盘......,根据数据的走向可分为输入流和输出流,这个走向是以内存为基准的,即往内存中读数据是输入流,从内存中往外写是 ...

随机推荐

  1. Dapper中数据表的字段(列)与实体属性不一致时,如何手动配置它们之间的映射?

    NET[C#]Dapper中数据表的字段(列)与实体属性不一致时,如何手动配置它们之间的映射? 问题描述 比如有如下的数据表结构:Person: person_id int first_name va ...

  2. BZOJ3573: [Hnoi2014]米特运输(树上乱搞)

    Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1669  Solved: 1031[Submit][Status][Discuss] Descript ...

  3. hdu 2444 The Accomodation of Students 判断是否构成二分图 + 最大匹配

    此题就是求最大匹配.不过需要判断是否构成二分图.判断的方法是人选一点标记为红色(0),与它相邻的点标记为黑色(1),产生矛盾就无法构成二分图.声明一个vis[],初始化为-1.通过深搜,相邻的点不满足 ...

  4. Java学习笔记2——数据类型和转换

    前提知识: 1字节=8bit:1bit以一个二极管表示,代表2个状态(0或者1):2bit代表22即4种状态(00,01,10,11),8bit即是28即256种状态,16bit即是65536种状态. ...

  5. 杭电 2095 find your present (2)【位运算 异或】

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2095 解题思路:因为只有我们要求的那个数出现的次数为奇数,所以可以用位运算来做,两次异或同一个数最后结 ...

  6. type="radio"样式修改

    input[type=radio],input[type=checkbox] { display: inline-block; vertical-align: middle; width: 20px; ...

  7. 团体程序设计天梯赛-练习集-L1-029. 是不是太胖了

    L1-029. 是不是太胖了 据说一个人的标准体重应该是其身高(单位:厘米)减去100.再乘以0.9所得到的公斤数.已知市斤是公斤的两倍.现给定某人身高,请你计算其标准体重应该是多少?(顺便也悄悄给自 ...

  8. leetCode 929 独特的电子邮件地址

    题目: 每封电子邮件都由一个本地名称和一个域名组成,以 @ 符号分隔. 例如,在 alice@leetcode.com中, alice 是本地名称,而 leetcode.com 是域名. 除了小写字母 ...

  9. 网上的CSS例子编写都不太严谨,如*{ margin:0;padding:0;}

    margin:0;padding:0; 一般情况下不可以用 *{margin:0;padding:0;} 来适配. 保证自己的严谨代码编写风格.

  10. Bonjour/Zeroconf with Arduino

    转自:http://gkaindl.com/software/arduino-ethernet/bonjour Bonjour/Zeroconf with Arduino DownloadVersio ...