Java之nio学习

来源:互联网 发布:射手男 知乎 编辑:程序博客网 时间:2024/05/22 14:19
    刚刚开始接触nio的时候有点迷惑,在网上也看过很多资料,大多都是讲了怎么用,没有个系统介绍。这里写写我的认识。

    1、nio是java传统网络IO的升级版,nio和io的关系可以看成http协议和tcp/ip协议(升级版)
    2、nio相比于io,是更精准的传输协议。具体的下面再说。

    然后说说nio和io的比较
    io传输直接是读取byte数组,由此产生的阻塞,缓冲区的额外开销等等问题在nio上没有的,原因如下:
    首先看看nio的传输单元:java.nio包下的ByteBuffer,ShortBuffer,FloatBuffer,IntBuffer,DoubleBuffer,LongBuffer,它们都继承于Buffer,

    Buffer含有4个属性:

private int mark = -1;  private int position = 0;  private int limit;  private int capacity; 

    由此可见,在传输的时候,就标注好了每个传输单元的长度/容量等一系列信息,自然在接受一端无需缓冲区了(我觉得很类似于http的格式,增加了报文头等),解决网络io长久以来的缓冲区的各种问题。

    网络传输阻塞问题在nio的解决。
    原有io在socket传输时一旦信息传送停止,等待接收的线程就会一直等待直到超时异常抛出。
    nio中采用的是基于事件驱动的事件-触发的模式来避免了阻塞,或者说是反应器设计模式(可能有的人也觉得是观察者模式,的确很类似:当被被观察体改变时,所有相关的依属体都得到通知,不过观察者只限于单个事件,反应器是与多公个事件源关联)。
    nio的非阻塞机制由Channel 类和Selector 类来完成,Selector是Channel的多路复用器,Channel官方解释为服务端和客户端的一种通信机制,每个 Channel 向 Selector 注册事件。当事件从客户机处到来时, Selector 将它们多路分用并将这些事件分派到相应的 Channel 。乍一看上去就是不是很熟悉?没错,很类似Socket = SocketServer.accpet(),然后分配一个新线程给对应的Socket,但是这里的Channel仅仅是作为信息传输,不能加入额外的逻辑处理。 
    相比于传统的网络IO,不需要用户自定义Thread来负责和客户端交互信息,只需要处理业务逻辑。

    以网络传输来说,运行步骤如下
    1、Channel向Selector注册
    2、有请求则Selector分配Channel进行信息传输(按照Buffer的“协议”),如果某个线程在一个Channel的I/O上阻塞时,另一个线程可以关闭这个Channel(实际物理传输层的上阻塞是不可避免的)。
    3、当某个Channel信息接受完整后,接受到的信息提交给用户自定义的处理模块完成业务处理,返回信息由这个Channel写回去

最后说说我认为的nio的缺点(其是我觉得也算不上自身的缺点),
    nio的确很强大,性能有提高,但是因为加入了Buffer机制,对于旧有的系统和非java.nio的系统来说,得有额外的支持。

 





原创粉丝点击