Java提供了哪些IO方式?IO, BIO, NIO, AIO是什么?
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 NIO和IO之间一个最大区别: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提供了哪些IO方式?IO, BIO, NIO, AIO是什么?的更多相关文章
- io编程,bio,nio,aio
本文会从传统的BIO到NIO再到AIO自浅至深介绍,并附上完整的代码讲解. 下面代码中会使用这样一个例子:客户端发送一段算式的字符串到服务器,服务器计算后返回结果到客户端. 代码的所有说明,都直接作为 ...
- IO回忆录之怎样过目不忘(BIO/NIO/AIO/Netty)
有热心的网友加我微信,时不时问我一些技术的或者学习技术的问题.有时候我回微信的时候都是半夜了.但是我很乐意解答他们的问题.因为这些年轻人都是很有上进心的,所以在我心里他们就是很优秀的,我愿意多和努力的 ...
- I/O模型系列之三:IO通信模型BIO NIO AIO
一.传统的BIO 网络编程的基本模型是Client/Server模型,也就是两个进程之间进行相互通信,其中服务端提供位置信息(绑定的IP地址和监听端口),客户端通过连接操作向服务端监听的地址发起连接请 ...
- (转)也谈BIO | NIO | AIO (Java版)
原文地址: https://my.oschina.net/bluesky0leon/blog/132361 关于BIO | NIO | AIO的讨论一直存在,有时候也很容易让人混淆,就我的理解,给出一 ...
- 也谈BIO | NIO | AIO (Java版--转)
关于BIO | NIO | AIO的讨论一直存在,有时候也很容易让人混淆,就我的理解,给出一个解释: BIO | NIO | AIO,本身的描述都是在Java语言的基础上的.而描述IO,我们需要从两个 ...
- java BIO/NIO/AIO 学习
一.了解Unix网络编程5种I/O模型 1.1.阻塞式I/O模型 阻塞I/O(blocking I/O)模型,进程调用recvfrom,其系统调用直到数据报到达且被拷贝到应用进程的缓冲区中或者发生错误 ...
- 3. 彤哥说netty系列之Java BIO NIO AIO进化史
你好,我是彤哥,本篇是netty系列的第三篇. 欢迎来我的公从号彤哥读源码系统地学习源码&架构的知识. 简介 上一章我们介绍了IO的五种模型,实际上Java只支持其中的三种,即BIO/NIO/ ...
- JAVA中的BIO,NIO,AIO
在了解BIO,NIO,AIO之前先了解一下IO的几个概念: 1.同步 用户进程触发IO操作并等待或者轮询的去查看IO操作是否就绪, 例如自己亲自出马持银行卡到银行取钱 2.异步 用户触发IO操作以后, ...
- BIO | NIO | AIO (Java版)
几篇解释的不错的文章: BIO NIO AIO NIO.2 入门,第 1 部分: 异步通道 API 使用异步 I/O 大大提高应用程序的性能
随机推荐
- Django(app的概念、ORM介绍及编码错误问题)
day61 Django中的APP: 什么是APP?以及为什么要用APP? project --> 项目 (老男孩教育大学校) ...
- FunDA(15)- 示范:任务并行运算 - user task parallel execution
FunDA的并行运算施用就是对用户自定义函数的并行运算.原理上就是把一个输入流截分成多个输入流并行地输入到一个自定义函数的多个运行实例.这些函数运行实例同时在各自不同的线程里同步运算直至耗尽所有输入. ...
- ActiveMQ使用线程池实现消息的生产与消费
jar文件:spring3.1jar,以及 项目src路径下文件:config.properties 读取config.properties文件JAVA类: package com.lejob.lej ...
- nginx配置跨域、gzip加速、代理详细讲解
1.配置跨域 这个很简单,直接打开配置nginx.conf ,在http下配置下面三行代码:当然如果你是想某一个虚拟主机下跨域,那就在哪个server下面添加 add_header Access-Co ...
- AngularJS入门之数据绑定
本篇我们看一下AngularJS中的数据绑定.虽然我们直到这篇才提到数据绑定,但事实上在前面几篇中我们已经非常熟练的运用AngularJS的数据绑定功能了! ngBind(ng-bind)/ {{ e ...
- 剑指offer四十二之和为S的两个数字
一.题目 输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的. 二.思路 数列满足递增,设两个头尾两个指针i和j,若ai + ...
- C++的开源跨平台日志库glog学习研究(二)--宏的使用
上一篇从整个工程上简单分析了glog,请看C++的开源跨平台日志库glog学习研究(一),这一篇对glog的实现代码入手,比如在其源码中以宏的使用最为广泛,接下来就先对各种宏的使用做一简单分析. 1. ...
- CSSREM
一个CSS的px值转rem值的Sublime Text 3自动完成插件. 安装 下载本项目,比如:git clone https://github.com/flashlizi/cssrem 进入pac ...
- python处理自然语言:1、调用LTP的API,2、使用pyltp
最近在学习处理自然语言处理,就发现LTP的(哈工大语言云),这个比我最先使用的jieba分词更好,词库更大,功能也更强大. 这里介绍两种方法:1.调用LTP的API,2.使用pyltp,这里的方法基于 ...
- 《Android应用性能优化》2——内存、CPU、性能测评
4.高效使用内存 4.1 说说内存 Android设备的性能主要取决于以下三因素: CPU如何操纵特定的数据类型: 数据和指令需占用多少存储空间: 数据在内存中的布局 4.2 数据类型 int和lon ...