一.首先什么是IO模型:

     就是用什么样的方式进行数据的接收和发送,和很大程度上决定了程序通信的性能。

二.为什么要有不同得IO模型,解决什么问题?

     首先在发送数据时,举例从应用A发送数据到应用B,首先应用A会先将数据发送到TCP中的缓冲区,然后再发送到应用B所在服务器的缓冲区,然后B应用从缓冲区中读取数据。

java更好的处理已读未读状态 java未读消息原理_数据

     这就涉及到一个问题,因为我们发送消息是间隔的,那么当应用B去缓冲区中拿数据时,如果缓冲区中无数据,是等待接收数据呢?还是直接返回。其实就涉及到阻塞和非阻塞的效果。

Java中的IO模型主要有三种BIO和NIO.AIO.其实主要是同步阻塞,同步不阻塞,异步不阻塞的区别。
这里的同步,异步,阻塞,非阻塞解释如下:

  1. 同步:当触发读写请求后,等待数据就绪并将数据从内核读取到用户空间,直到返回数据.
    简单来说就是应用发送完指令要参与整个过程,直到返回数据
  2. 异步:当触发读写请求后(这里不是去缓冲区读写,仅仅告诉内核我想去读取数据),直接返回,内核帮助你完成整个操作后,帮你将数据从内核复制到应用空间,再通知你.
    简单来说就是应用发送完指令不再参与整个过程,直接返回等待通知.
  3. 阻塞:试图对缓冲区进行读写时,当前不可读或者不可写(内核数据没有准备好的情况下),程序进行等待,直到可以操作。
  4. 非阻塞:试图对缓冲区进行读写时,当前不可读或者不可写,读取函数马上返回。

三.各种优缺点:


  •      实现方式:服务器每收到一个请求,就会创建一个线程去读取对应数据,同时线程也不知道什么时候会有数据,所以会阻塞等待。这样如果一下子收到成千上万的请求,就会创建成千上万个线程去读取数据,非常浪费资源。只适用于连接数少且固定的架构.

  •      实现方式:有专门的线程去轮询完成对数据状态询问的操作(当前是否有数据可读取),当有数据准备就绪后分配对应的线程去读取数据,这就相比前一种就可以节省大量的线程资源出来。
    适用于连接数多且连接较短的架构.

  •       应用程序将具体操作告诉内核(比如说我要读一个数据),此时应用程序就直接返回了,当内核完成操作后通知应用程序,适用于连接数多且连接较长的架构.
    参考博客:
    https://zhuanlan.zhihu.com/p/115912936