Java中IO——NIO
来源:互联网 发布:淘宝网店店铺号购买群 编辑:程序博客网 时间:2024/05/18 02:18
一、引入
当引入一些新功能的时候,那说明之前的设计可能还需要完善。
1、阻塞式
在传统的IO输入输出中,如果我们从流中去读数据,而数据源中没有数据时,程序就会阻塞该线程。阻塞式线程的一种基本状态,可以理解成线程就在那里等着,什么也不做。
显然,这种阻塞式的io如果正常执行还好,一旦数据缺失或网络故障,就没什么优点可言了。
2、效率不高
传统IO的介绍中,我们把流比作水管中的水滴,读和写操作都在操作“水滴”,而且一次只能操作一个“水滴”(字节),效率确实有限。
因此,java4引入了NIO来完善这些地方。
二、重要特性
NIO可以理解成New IO,百科上说是Non-Blocking非阻塞式IO,这个名字就比较直白了。当然,除了非阻塞的优点,他还有别的特性。
内存映射
NIO也是为了解决输入输出的问题,由于传统方法效率不高,NIO采用了内存映射的方式来提高效率。具体通过Channel对象来体现。
Channel通道是模拟的传统IO,可以通过它读取和写入数据。它不同之处在于提供了map()方法,可以直接将一块数据映射到内存。
标准访问:
内存映射:
另外,通道是双向的,而流式单向的。通道可以用于读、写或同时读写。
缓冲支持
传统IO是面向流的,NIO是面向缓冲的。
Buffer是一个数组容器,发送到Channel的对象都必须先放到Buffer中,而从Channel中读取的数据也必须先放到Buffer中。简单的说,Buffer类似Channel对外交互的一个中介,如果Channel的读写都不通过Buffer了,那缓冲也没什么意义了。
Buffer是一个抽象类,子类包括了基本数据类型的对应类:ByteBuffer、CharBuffer、ShortBuffer、IntBuffer等。
常用变量:
// Invariants: mark <= position <= limit <= capacity //可选的标记 private int mark = -1; //位置 private int position = 0; //界限 private int limit; //容量 private int capacity; //构造函数 // Creates a new buffer with the given mark, position, limit, and capacity, // after checking invariants. // Buffer(int mark, int pos, int lim, int cap) { // package-private if (cap < 0) throw new IllegalArgumentException("Negative capacity: " + cap); this.capacity = cap; limit(lim); position(pos); if (mark >= 0) { if (mark > pos) throw new IllegalArgumentException("mark > position: (" + mark + " > " + pos + ")"); this.mark = mark; } }
其中,这几个变量的关系如下所示:
重要方法:
/** * Flips this buffer. The limit is set to the current position and then * the position is set to zero. If the mark is defined then it is * discarded. * * <p> After a sequence of channel-read or <i>put</i> operations, invoke * this method to prepare for a sequence of channel-write or relative * <i>get</i> operations. For example: * */ public final Buffer flip() { limit = position; position = 0; mark = -1; return this; }
flip()方法将limit放在position的位置,然后将position的值设为0,mark恢复初始化值-1,可参考上面的图。此时这三个变量都已经恢复初值,Buffer的读写指针回到了开始位置。装入数据结束后调用该方法,为输出数据做好了准备。
/** * Clears this buffer. The position is set to zero, the limit is set to * the capacity, and the mark is discarded. * */ public final Buffer clear() { position = 0; limit = capacity; mark = -1; return this; }
clear()不是清除数据内容,将容量capacity值赋给了limit。在输出数据结束后,调用clear,为再次向Buffer装入数据做准备。
单线程处理
NIO中使用单个线程来处理多个Channel,这样一来,不会因为线程间的上下文切换付出大量的开销,不需要考虑共享资源的问题。一个线程可以管理多个网络连接。具体的实现是Selector。
Selector选择器的工作原理:首先向Selector中注册Channel,然后Selector就可以检测到一个或多个NIO通道,并且能够了解每个通道是否已经做好准备进行读写。
是不是有点类似观察者模式、监听的赶脚( ⊙ o ⊙ )!
说了这么多,这里也可以通过对比图来学习。
图一:old io
图二:nio
三、小结
本篇博客通过对比新旧IO,来介绍了NIO几大特性。侧重原理的理解,读者可再找些小demo练习一下。
NIO中主要强调的是non-blocking非阻塞io(即非bio),在java7之后推出了NIO.2,增加了异步IO的实现(即aio)。两者结合非阻塞异步io,差不多就完美了。(^o^)/~
- Java中IO——NIO
- Java NIO 系列—Java NIO 与 IO
- Java中IO与NIO
- Java中的新IO—NIO
- 【IO/NIO】Java IO/NIO
- java中io与nio的使用
- Java中 NIO与IO的区别
- Java中NIO和IO的比较
- java中IO、NIO、AIO(NIO2.0)
- java中NIO和IO的区别
- 【IO/NIO】Java NIO浅析
- JAVA基础(10)——IO、NIO
- 尚硅谷java——NIO(New IO)
- JAVA NIO总结(四)—网络和异步IO
- java IO & NIO
- Java NIO vs. IO
- Java NIO vs. IO
- Java NIO vs. IO
- HDU 3790 最短路径问题(Dijkstra)
- 常用的正则表达式
- 面向项目(八)—— #if defined 与 #ifdef
- 各种Android Dialog创建及其监听事件实现
- 使用google的开源框架Volley,功能一:网络请求Json数据
- Java中IO——NIO
- 遍历Map的四种方法
- linux-Centos-7-64位:6、 svn安装及配置
- poj 1182食物链(带权并查集)
- 阿里云之简单lamp搭建
- EyeKey诚邀您莅临CCTC大会B11展位体验不一样的人脸识别!
- 【深度】程序员、黑客和开发者的区别
- 【ANDROID布局问题总结】Activity启动后EditText是否自动弹出输入法虚拟键盘的问题
- jquery正则表达式基础辅助式理解