NIO学习笔记(理论知识)

三大核心部分

Channel(通道)
Buffer(缓冲区)
Selector(选择器)

NIO跟传统IO的区别:IO是面向流的,NIO是面向缓冲区的。面向流意味着每次从流中读取一个或多个字节的数据直到读完所有的数据,他们没有被缓存到任何地方,他不能前后移动流中的数据,如果需要前后移动流中的数据需要先将他缓存到一个缓冲区。NIO的缓冲导向有所不同,将数据读取到一个他将处理的缓冲区中,需要时候再缓冲区中前后移动得到想要的数据,增加了处理的灵活性,但是还需要检查缓冲区中包含所有您需要处理的数据。而且需要确保有更多数据进入缓冲区的时候不会覆盖原本缓冲区中的数据。

IO的各种流是堵塞的,这意味着一个线程write或者read的时候这个线程是被堵塞的,直到有一些数据被读取完毕或者完全写入。在该期间线程不能做任何其他事情。NIO的非堵塞模式使一个线程从某通道发送请求读取数据时,但是他仅能得到目前可用的数据,如果目前没有数据可用就什么都不会获取,而不是保持堵塞,所以直至数据变得可用之前,该线程还可以去做其他事情。非阻塞的写亦是如此。一个线程在请求数据时,不需要等待数据完全写入,这个时候线程可以去干别的时候。线程通常将非阻塞IO的空闲时间用于在其他通道上执行IO操作,所以一个单独的线程现在可以管理多个输入和输入通道。

Channel

Channel和IO中的流是差不多的意思。只不过Stream的单向的,譬如InputStream和OutPutStream都是单向的,Channel是双向的,可以用来读也可以用来写。
NIO中Channel的主要实现有:

FileChannel
DatagramChannel
SocketChannel
ServerScoketChannel

Buffer

NIO中常用的buffer如下:

ByteBuffer CharBuffer DoubleBuffer FloatBuffer IntBuffer LongBuffer ShortBuffer
MappedByteBuffer HeapByteBuffer DirectByteBuffer(这三个目前不了解)

Selector

Selector运行单个线程,处理多个Channel,如果你的应用打开了多个Channel,但是每个的流量都很低,使用Selector会很方便,例如在一个聊天服务器中。要使用Selector就得像Selector注册Channel,然后调用他的select()方法。这个方法会一直阻塞到某个注册通道的事件发生,一旦这个方法返回,线程就可以处理这些事件,例如有新的连接加入进来,接收数据等。

API记录

ByteBuffer的4个标记

capacity:缓冲区数组的总长度
limit:缓存区中可操作数据的临界点: limit<=capacity
position:下一个要操作的元素的位置
mark:用于记录position的前一个位置|或者是-1

ByteBuffer.flip()将position设置为0,将limit设置为position的位置

ByteBuffer.clear():将position设置为0,将limit设置为capacity的位置,ByteBuffer内的数据也不保留

ByteBuffer.compact():将所有未读的数据拷贝到Buffer的初始位置,丢弃掉已读的数据,并将position设置为未读数据的最后一个位置,将limit设置为capacity的位置

ByteBuffer.mark():标记一下当前position的位置,并且可以调用ByteBuffer.rest()恢复到这个position

ByteBuffer.rewind():将position设置为0,所以可以重读Buffer中的所有数据,limit保持不变。

热爱编程的朋友可以加入QQ技术交流群:1026659175

posted @ 2020-05-18 15:31  lyp-make  阅读(124)  评论(0)    收藏  举报