图解java的BI0,NIO,最简单直白的理解同步和异步IO模型

来源:互联网 发布:sap ariba offer知乎 编辑:程序博客网 时间:2024/04/19 21:17

最古老的javaIO通信模式BIO,即阻塞IO,同步调用,性能低:

在服务器端:有专门的客户连接 接收器Acceptor,当有新的客户端连接到达后,Acceptor负责第一步连接,然后给每一个客户端连接创建一个新的线程来处理对应的业务;处理完成后,通过输出流返回给客户端,并将线程销毁,这也是最典型的一对一服务模型。

对应模型图如下:


从图中可以明显看出对应Web Browser1,2,3,4 服务器端分别创建了线程New Thread1,2,3,4对应处理来应答对应的请求。

伪异步模型IO;也被成为M:N客户服务模型。即通过线程池模型的形式用M个线程来服务N个客户端的连接;其中M的大小可以根据服务器的配置来设置最大值,而可服务客户端个数N则可以远远的大于M.这样来提高服务器的服务效率,提高线程利用率。同BIO模型类似,只不过,Acceptor接受客户端请求后,不再独立启动线程来处理,而是将客户请求交给线程池来处理,从而减少线程的创建数量,提高线程利用率,增加服务器的处理能力;

对应的模型如下图:


从上图可以看出,M:N的iO模型中的web Browser1,2,3,4最终都由Acceptor交给了Task任务队列,然后由Thread Pool来执行任务,并将最终的响应结果返回给客户端。

其中ThreadPool中线程的数量M和Task任务队列的长度的设置,将会影响到服务器处理客户端请求的能力,合理的配置线程池和Task队列长度,才能使得服务器处理能力达到最大;而其具体大小需根据实际需求来决定;

异步IO:NIO模型;有人叫做New IO,来区别BIO,也有人叫Non-block IO,不过都是表示非阻塞IO,与阻塞Io对应,客户端的Socket与服务器端的ServerSocket,分别为:SocketChannel和ServerSocketChannel两种不同的套接字来实现通信;不过他们即支持非阻塞通信模式,也支持阻塞通信模式,如果使用需要手动设置为非阻塞模式;这也是高效率和高性能的首选模式。

NIO服务端通信序列图:


从上图可以看出服务器端创建了ServerSocketChannel,创建了多路复用器Selector,然后将服务器的服务地址和端口绑定到SSC中,并注册给多路复用器,并启动多路复用器来处理不同的事件,包括连接事件,读取事件,写事件。当然对于每一个客户端的连接,都必须先建立连接,然后才能异步读和异步写,但是每一个客户端的读写事件并没有先后顺序,而是通过Selector选择器轮询所有的事件,在通过读写缓冲区准备好的事件(已经就绪),就会被选中并处理,然后完成对应的事件。如果A客户端先建立连接,但是需要读大量数据,则其读事件就不会处于就绪状态,也就不会被选择器选中,而B客户端后建立连接,但是读取数据少,很快就处于就绪状态,那么服务器就会处理B的数据,然后将结果写入写缓冲区,当写数据完成并就绪,则会触发写事件,返回给客户端。而此时如果A的读数据完成处于就绪状态,则处理器会继续处理A的读事件,之后服务器处理完成,并异步些人写缓冲区,处理逻辑同B的写逻辑;

Nio客户端通信时序图:


从上图可以看出,客户端创建SocketChannel并设置为非阻塞模式,并创建多路复用器Selector,客户端需要先创建连接,然后是异步读事件,然后是异步写事件,当然客户端和服务器端的连接(通道)一旦建立,则轮询器会不停的判断,当然也可以设置每过几秒来轮询一次,是否处于读就绪或者写就绪,如果缓冲已经就绪,则会处理对应的读写事件。对于读写事件的处理过程基本同服务器端。



0 0