IO一直是软件开发中的核心部分之一,而随着互联网技术的提高,IO的重要性也越来越重。纵观开发界,能够巧妙运用IO,不但对于公司,而且对于开发人员都非常的重要。Java的IO机制也是一直在不断的完善,以应对日见增多的流量。

Java IO的方式

  首先,传统java.io包提供了诸如File的抽象,输入,输出流。交互方式是同步,阻塞;

  第二,在java 1.4中引入NIO框架(java.nio包),提供了Channel,Selector,Buffer等抽象,构建多路复用的,同步非阻塞IO,同时提供了更接近操作系统底层的高性能数据操作方式;

  第三,在Java 7中,NIO有了进一步的改进,也就是NIO 2。其引入了异步非阻塞IO方式,或者说AIO(Asynchronous IO)。异步IO基于事件和回调机制。

传统BIO

  传统BIO,采用BIO编程通信模型的服务端,通常由一个独立的Acceptor线程负责监听客户端的连接。它接收到客户端连接请求之后为每个客户端创建一个新的线程进行链路处理,处理完成后,通过输出流返回给对应的客户端,然后销毁线程。

  服务端提供IP地址和监听的端口,客户端通过TCP的三次握手与之连接,连接成功后,双方通过套接字通信。

  ServerSocket负责绑定IP地址,启动监听端口;Socket负责发起链接操作。连接成功,双方通过输入和输出流进行同步阻塞式通信。

  “你来了,我才往”的交流方式。

  ps, Java.net提供的API,如Socket,ServerSocket,HttpURLConnection也归与同步阻塞IO类库,因为网络通信同样是IO行为。

  优点:代码简单,直观,维护方便。

  缺点:IO效率极低,影响性能,却反弹性处理。

  当吞吐量增大了,有妙招:线程池。

  使用线程池管理线程,避免频繁创建,销毁线程的开销。

  但是,其底层使用的依然是同步阻塞IO,通常被称为“伪异步IO模型”,真的是治标不治本。

看官留意

  IO不仅仅时对文件的操作,网络编程中,比如Socket通信也是典型的IO操作。

  输入流(InputStream),输出流(OutputStream),用于读取或写入字节的(在java中以Stream结尾)。

  而Reader/Writer操作字符,增加了字符编解码等功能(在java中以Reader/Writer结尾)。本质上计算机操作的都是字节,不管是网络通信还是文件读取,Reader/Writer相当于构建了应用逻辑和原始数据之间的桥梁。

  BufferdOutputStream,等带缓冲区的实现,可以避免频繁的磁盘读写,进而提高IO处理效率。

区分异步和同步

  同步,一种可靠有序的运行机制,在进行同步操作时,后续的任务要等待当前调用返回;

  异步,其他任务不需要等待当前调用是否返回,依靠事件,回调机制来实现任务调用。

阻塞和非阻塞

  阻塞,当前线程处于阻塞状态,无法从事其他任务,只有当条件就绪才能继续;

  非阻塞,不管IO操作是否结束,直接返回,相应的操作在后台继续处理。

由此总结:同步和异步是结果,阻塞和非阻塞是过程。

NIO

  New IO,或者Non-Block IO,非阻塞同步模式。

  设计原理:

    1. 服务端与客户端通过Channel通信;

    2. NIO在Channel上读写;

    3. Channel被注册到Selector多路复用器上。Selector通过一个线程轮询这些Channel,找出已经就绪的Channel。

NIO通过线程的轮询,实现非阻塞IO

NIO的组成部分:

  1. Buffer  缓冲区;高效的数据容器

    不同的是BIO将数据直接读写到Stream对象中

    NIO的数据操作都是在缓冲区中进行的

    缓冲区实际上是一个数组,常见类型ByteBuffer,CharBuffer,ShortBuffer,IntBuffer,LongBuffer,FloutBuffer,DoubleBuffer;

  2. Channel 在NIO中被用来支持批量式IO操作的一种抽象,与流不同,通道是双向的。

File/Socket,通常被认为是比较高层次的抽象,而Channel则是更加偏向操作系统底层的一种抽象,这也使得NIO得以充分利用现代操作系统底层机制,进行性能优化。分两大类:网络读写SelectableChannel(子类包括SocketChannel和ServerSocketChannel);文件操作(FileChannel);

  3. Selector  是NIO实现多路复用的基础。它提供一种高效机制,不断轮询注册在其上的Channel,找出处于就绪状态,通过SelectionKey取得就绪的Channel集合,进行后续的IO操作。服务端只要提供一个负责Selector轮询的线程即可,实现单线程对多Channel的高效管理,也是基于操作系统底层机制;

  4. Charset  提供Unicode字符串定义,NIO也提供了相应的编解码等。

Java NIOIO之间一个最大区别:IO是面向流的,NIO是面向缓冲区的。

AIO Asynchronous IO

  NIO 2 ,在Java 7提出,NIO的升级版。实现非阻塞异步的通信模式;

  提供异步文件通道和异步套接字通道;

  其read,write方法的返回类型都是Future对象;

  而Future模型是异步的,其核心思想是:去主函数等待时间;

  基于事件和回调机制。

小结

  IO,阻塞同步通信模式,客户端与服务端三次握手,简单,吞吐量小。关键词:Socket和ServerSocket;

  NIO,非阻塞同步通信模式,客户端与服务端通过Channel连接,采用多路复用器轮询注册的Channel。关键词:SocketChannel 和 ServerSocketChannel;

  AIO,非阻塞异步通信模式,基于事件和回调机制,采用异步通道实现异步通信。关键词:AsynchronousSocketChannel 和 AsynchronousServerSocketChannel。

写在后面

主要参考资料

杨晓峰《Java核心技术36讲》

阿_毅《Java之IO,BIO,NIO,AIO知多少?》

Java提供了哪些IO方式?IO, BIO, NIO, AIO是什么?的更多相关文章

  1. io编程,bio,nio,aio

    本文会从传统的BIO到NIO再到AIO自浅至深介绍,并附上完整的代码讲解. 下面代码中会使用这样一个例子:客户端发送一段算式的字符串到服务器,服务器计算后返回结果到客户端. 代码的所有说明,都直接作为 ...

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

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

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

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

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

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

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

    关于BIO | NIO | AIO的讨论一直存在,有时候也很容易让人混淆,就我的理解,给出一个解释: BIO | NIO | AIO,本身的描述都是在Java语言的基础上的.而描述IO,我们需要从两个 ...

  6. java BIO/NIO/AIO 学习

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

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

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

  8. JAVA中的BIO,NIO,AIO

    在了解BIO,NIO,AIO之前先了解一下IO的几个概念: 1.同步 用户进程触发IO操作并等待或者轮询的去查看IO操作是否就绪, 例如自己亲自出马持银行卡到银行取钱 2.异步 用户触发IO操作以后, ...

  9. BIO | NIO | AIO (Java版)

    几篇解释的不错的文章: BIO NIO AIO NIO.2 入门,第 1 部分: 异步通道 API 使用异步 I/O 大大提高应用程序的性能

随机推荐

  1. PHP之旅5 php的函数

    函数的结构 php的函数和其他语言的函数基本类似,和C语言比较的话主要区别在于php是一个弱语言,对类型不敏感,在函数的表现上就是,php函数没有类型定义,不像语言即使无参也要定义为void,而且不管 ...

  2. Jmeter之Bean shell使用

    转载地址:http://www.cnblogs.com/puresoul/p/4915350.html 一.什么是Bean Shell BeanShell是一种完全符合Java语法规范的脚本语言,并且 ...

  3. nacicat premium 快捷键

    1.ctrl+q          打开查询窗口 2.ctrl+/           注释sql语句 3.ctrl+shift +/  解除注释 4.ctrl+r          运行查询窗口的s ...

  4. 使用git时出现Please make sure you have the correct access rights and the repository exists.问题已解决。

    使用git时,出现Please make sure you have the correct access rights and the repository exists.问题已解决. 今天我在使用 ...

  5. 原生ajax封装,包含post、method方式

    原生ajax封装,包含post.method方式 function ajax(method, url, data, success) { var xhr = null; try { xhr = new ...

  6. h5仿微信、支付宝数字键盘|微信支付键盘|支付宝付款键盘

    html5仿微信支付数字键盘|仿支付宝键盘|h5仿微信密码输入键盘|自定义数字键盘 很早之前由于项目需求,就有开发过一个h5仿微信支付键盘,这几天就把之前的数字键盘模块独立出来,重新整理开发成demo ...

  7. 前后端分离最佳实现,使用Nuxt.js快速搭建单页SSR应用

    通常我们搭建ssr应用需要自己选择多个组件集成到一起 webpack babel loaders router server-render 各种入口配置等 如果是基于vue+vuex+vue-rout ...

  8. [转载]7款开源ERP系统比较

    现在有许多企业将ERP项目,在企 业中没有实施好,都归咎于软件产品不好.其实,这只是你们的借口.若想要将ERP软件真正与企业融合一体,首先得考虑企业的自身情况,再去选择适合的 ERP软件. 如果你的企 ...

  9. Names and Identifiers

    JLS:https://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.2 Not all identifiers in a pr ...

  10. vue-resource使用笔记

    基本语法 //基于全局Vue对象使用http Vue.http.get('/someUrl', [options]).then(successCallback, errorCallback); Vue ...