JavaBascisN5: IO And NIO Part2.NIO

NIO


相关概念

一、缓存区:表示数据存放的容器,提供可读写的数据缓存区

直接缓存区:allocateDriect    在内存中直接创建,绕过JVM的堆和栈。

                 —直接操作物理磁盘,不复制    

非直接缓存区:allocate          直接在JVM创建。           

                —先复制物理磁盘的值,在JVM中操作,再读写到物理磁盘

速度 :直接缓存区>非直接缓存区      

创建和销毁的开销:直接缓存区>非直接缓存区

二、字符集:用来对缓存数据进行解码和编码,在字节和Unicode字符之间转换

IO流:"".getBytes(“UTF-8”)的方式对目标字符串进行编码处理,此方法
是返回的是当前字符串的Byte[] 数组形式,转换回去的方式为: new String(Byte[]
byte,'"字符集")。

NIO:在java1.7以后,NIO提供了StandardCharsets类,此类里面提供了NIO方式
的将字符串转换为字节数据的方式:"string".getBytes(StandardCharsets.UTF_8);

三、通道:用来接收或发送数据,提供与文件、套接字等的连接。

通道即为:Channel -- 通道相当于“流”,但是不参与读写数据,作为数据的传输通道(这个通道是双向的)存在。其需与ByteBuffer进行交互合作,buffer并能在Channel中
实现双向读写数据。    【双向、不读写、ByteBuffer】

四、选择器:NIO中最有意思的部分--> 非阻塞IO

通常在进行同步I/O操作时,如果读取数据,代码会阻塞直至有可供读取的数据。同
样,写入调用将会阻塞直至数据能够写入。传统的Server/Client模式会基于TPR(Thread
per Request线程的意思),服务器会为每个客户端请求建立一个线程,由该线程单独负责处
理一个客户请求。这种模式带来的一个问题就是线程数量的剧增,大量的线程会增大服务器
的开销。大多数的实现为了避免这个问题,都采用了线程池模型,并设置线程池线程的最大
数量,这由带来了新的问题,如果线程池中有200个线程,而有200个用户都在进行大文件
下载,会导致第201个用户的请求无法及时处理,即便第201个用户只想请求一个几KB大小
的页面。传统的Server/Client模式如下图所示:

Dispatch : 线程组
NIO中非阻塞
I/O(https://blog.csdn.net/u014631304/article/details/77684667 同步和
异步,阻塞与非阻塞之间的关系)采用了基于Reactor[rɪ'æktә]反应器模式
(1)的工作方式,I/O调用不会被阻塞,相反是注册感兴趣的特定I/O事件,如
可读数据到达,新的套接字连接等等,在发生特定事件时,系统再通知我们。
NIO中实现非阻塞I/O的核心对象就是Selector,Selector就是注册各种I/O事件
地方,而且当那些事件发生时,就是这个对象告诉我们所发生的事件,如下图所
示:

Reactor反应器模式:或者说观察者模式--->是用于处理并发服务请求,并将请
求提交到一个或多个服务处理程序的时间设计模式。 

SelectionKey:当有读写等任何注册事件发生时,可以从Selector中获得相应的
SelectionKey,同时从 SelectionKey中可以找到发生的事件和该事件所发生的
具体的SelectableChannel,以获得客户端发送过来的数据。
 

JavaNIO三大组件:  Buffer、Channel、Selector

java.nio包

一.Buffer

本质:

核心:ByteBuffer

理解:Buffer理解为一个数组,操作Buffer和操作数组、类集差不多,不过是在NIO场景。

         —IntBuffer对应int[]、CharBuffer对应char[]、DoubleBuffer对应double[]

         —MappedByteBuffer用于实现内存映射文件

属性:position、limit、capacity                       位置、限制、容量

方法:put()添加数据、flip()切换到读模式、get()获取数据、clear()清空数据

读模式:

写模式:

切换模式:flip() :position归零

对比:

        读模式:先mark(),然后reset()

         —mark():临时保存position值,每次调用此方法,mark设为当前的position,便于后续需要的时候使用

         —reset():调用reset(),position回到mark的地方

        写模式

         —rewind():重置position为0=从头读写Buffer

         —clear():填充Buffer,读取数据,调用clear(),重新填充。【覆盖填充】

         —compact():填充Buffer,读取数据,调用clear(),将position到limit间的数据左移,

                            重新填充[【接力填充】

常用ByteBuffer,其他只是做了些包装

初始化Buffer           ByteBuffer byteBuf = ByteBuffer .allocate(int capacity)  静态方法

填充Buffer               byteBuf.put();

提取Buffer中的值    byteBuf .flip();

猜你喜欢

转载自blog.csdn.net/ddhmbbklyk2018/article/details/81607066