java-----NIO总结(四)

我们知道java中的IO经历了BIO到NIO再到AIO的发展,具体来讲的话BIO是同步阻塞式IO,NIO是同步非阻塞式IO,而AIO是异步非阻塞式IO,前面我们分析了BIO和NIO的用法,至于AIO目前我还没有研究的想法,先把BIO和NIO研究清楚了再说吧,这篇博客我对前面的内容进行总结,如果你没有看过前面的博客,强烈推荐你看下,下面是索引链接:

        java-----NIO总结(一)

       java-----NIO总结(二)

       java-----NIO总结(三)
        首先是同步/异步,阻塞/非阻塞的区别:
        同步/异步是属于操作系统级别的,指的是操作系统在收到程序请求的IO之后,如果IO资源没有准备好的话,该如何响应程序的问题,同步的话就是不响应,知道IO资源准备好;而异步的话则会返回给程序一个标志,这个标志用于当IO资源准备好后通过事件机制发送的内容应该发到什么地方;
        阻塞/非阻塞是属于程序级别的,指的是程序在请求操作系统进行IO操作时,如果IO资源没有准备好的话,程序该怎么处理的问题,阻塞的话就是程序什么都不做,一直等到IO资源准备好,非阻塞的话程序则继续运行,但是会时不时的去查看下IO到底准备好没有呢;

        (1):我们常用的Socket用法,它里面的accept和read都会造成我们程序的阻塞,对于客户端来说,在发出请求之后,都会一直等待,直到服务器返回结果或者网络出现异常,对于服务器端来说,对于客户端的请求事件只能一个一个的进行处理,这虽然客户端A和客户端B的请求是同时发送的,但是在服务端的执行是顺序执行的,可以用下图来反映这个过程:

                             

        (2):随后,为了解决服务端正在处理客户端A的请求的时候不能响应客户端B请求这个问题,我们为每个客户端创建了一个线程,这样的话,每个客户端具体的执行都是在独立的线程中执行的,只要在主线程中没收到一个客户端连接就创建一个线程来处理与这个连接有关的内容就可以了,主线程还是继续监听有没有客户端接入就可以了;这个过程可以通过下图来反映:

                                

         (3):但是这种方法并没有解决掉在单个客户端线程中的阻塞现象,在单个线程中还是存在一直等待的现象,而且为每个客户端创建一个对于服务端来说压力比较大,而且在很多情况下是没什么必要的,java为了解决需要创建多个线程这个问题,引入了NIO,他在服务端是不需要为每个客户端都创建一个线程的,而只是给Selector创建一个监控线程,我们可以使用Selector来监控那些已经准备就绪的通道,将里面的数据写入Buffer缓存区,或者将Buffer缓存区中的数据写入通道,而且只有Selector可能会陷入阻塞状态,对于通道和缓存区的操作是不会陷入阻塞状态的;他的具体实现原理图是:

              

     

posted @ 2017-10-13 18:09  songjy2116  阅读(82)  评论(0编辑  收藏  举报