JAVA中NIO,BIO,AIO理解分析

在理解这三种IO模型之前需要知道同步异步,阻塞和非阻塞这几种概念,还要知道什么是同步阻塞,异步阻塞,同步非阻塞,异步非阻塞。
上面的内容在另一篇博客里有讲;
通过这个连接可以查看:
https://blog.csdn.net/weixin_43404016/article/details/106881672

  1. BIO
    BIO其实就是一种同步阻塞IO,在对数据的读写都是需要在一个线程内完成的。
    BIO就是一个请求对应一个处理,而每一个处理对应的就是一个线程,因此在使用BIO意味着需要很多的线程开销。
    下面这是一张BIO的通信模型图

JAVA中NIO,BIO,AIO理解分析
使用BIO通信模型的服务端,通常是有一个Acceptor(接收器)来负责监听客服端的连接请求。当监听接收到客服端的连接请求的收,就可以通过socket来进行读写操作,这个时候就不再接收客服端的请求,知道当前的连接结束。

但是可以通过多线程来解决这个问题,当有一个客服端的请求过来的时候,那就创建一个新的线程,用来进行和客服端进行连接,然后当数据读写操作结束之后就将这个线程销毁。但是当请求多的时候就造成了很大的线程开销,线程的创建也是很消耗资源的,这个也可以通过线程池来进行改善。

但是当请求数过多的时候可能就会造成创新新线程失败,线程堆栈溢出,最终导致服务器宕机,无法提供服务。

  1. NIO
    NIO是一种同步非阻塞的IO模型,NIO通过Selector,Channel,Buffer来实现非阻塞的IO操作,它的原理入下图
    JAVA中NIO,BIO,AIO理解分析
    上图中的Channel可以看作是一个非阻塞的通道,在通道的两边都是可以进行数据读写操作。Selector实现了用一个线程来管理多个通道,它类似于一个观察者。在实现的时候,把需要处理的Channel的IO事件注册给Selector。Selector内部的实现原理为:对所有注册的Channel进行轮询访问,一旦轮询到一个Channel有注册的事件发生,比如有数据来了,那么它就通过传回Selection-key的方式来通知开发人员对Channel进行数据读或者写操作。Key封装一个特定Channel和一个特定的selector之间的关系。这种通过轮询的方式在处理多线程请求的时候不需要上下文的切换,而是采用多线程的实现方式在线程之间切换的时需要上下文的切换,同时也需要进行压栈于弹栈操作。
    Buffer用来保存数据,可以用来存放从Channel读取的数据,也可以存放使用Channel进行发送的数据。

  2. AIO
    AIO是异步非阻塞的IO模型;
    AIO是异步执行,在执行的时候它不需要等待,可以去做别的事情,当有结果返回的时候会通知它进行接收数据。