概述
常见的网络io分为两种情况,BIO(block-io)和NIO(non-block-io),分别位于java.io和java.nio。
BIO,是阻塞的io,采用一个线程处理一个连接的方式,就算这个连接什么消息都没有传递,该线程也无法去处理另外的连接。
NIO,相对于BIO,采用一个线程处理所有的连接。也是本文重点描述对象。
NIO的几大名词,
buffer
channel
selector
buffer顾名思义是缓冲区的意思,主要特征有四个,capacity、limit、position、mark,跟数组类似。capacity非负数且不可变,limit是第一个不可被操作的元素的索引,position是下一个元素的索引,mark作为position的替身,用于作标记。以下为原文解释:
A buffer's capacity is the number of elements it contains. The capacity of a buffer is never negative and never changes.
A buffer's limit is the index of the first element that should not be read or written. A buffer's limit is never negative and is never greater than its capacity.
A buffer's position is the index of the next element to be read or written. A buffer's position is never negative and is never greater than its limit.
创建
以Buffer的子类ByteBuffer为例,从内存的分配方式来看,有两种创建方式,一种是基于JVM的堆分配(non-direct),一种是基于操作系统的内存分配(direct),采用JNI接口,一般而言,direct无论在创建和释放的资源开源都大于non-direct。direct建议使用在占据内存很大的生命周期很长的应用场景,而目的就在于提高程序的性能,降低gc带来的开销。
从初始化的方式来看,也有两种,一种是只初始化分配内存,另一种是根据已有的bytep[]初始化,需要注意的是,这两种初始化后的Buffer的position不同,在get()的时候注意。
重置
clear() ,rewind() ,flip(),这三个接口都可以起到重置作用。原理都是基于capacity、limit、position、mark这四个变量的设置。以下是源代码。
public final Buffer clear() { position = 0; limit = capacity; mark = -1; return this; }
public final Buffer rewind() { position = 0; mark = -1; return this; }
public final Buffer flip() { limit = position; position = 0; mark = -1; return this; }
案例
ByteBuffer buf = ByteBuffer.allocate(4);buf.put("test".getBytes());buf.flip();buf.mark();System.out.println((char)buf.get());System.out.println((char)buf.get());System.out.println((char)buf.get());System.out.println((char)buf.get());buf.reset();System.out.println((char)buf.get());
testt
其它
buffer分为只读和读写模式,不是线程安全
相关资料
//oracle官方解释-Buffer
//oracle官方解释-ByteBuffer
//写的很详细,图文并茂的一篇博客
PS
下方是我个人订阅号,会一直更新各类技术文章,欢迎关注 :)