NIO基本介绍

同步和异步,同步指的是应用程序会直接参与IO读写操作,用阻塞或者长轮询的方式来获取数据。异步指的是IO交给操作系统,完成IO读写后通知程序,程序直接拿走数据。

  • BIO:同步阻塞式IO,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。 Socket/ ServerSocket
  • NIO:同步非阻塞式IO,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。 SocketChannel/ ServerSocketChannel
  • AIO(NIO.2):异步非阻塞式IO,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。
    • Buffer 缓冲区
    • Channel 管道
    • Selector 多路复用器

NIO基本概念

Buffer几个基本类型,ByteBuffer,CharBuffer,ShortBuffer,IntBuffer,LongBuffer,FloadBuffer,DoubleBuffer。缓冲区是为了存放数据

Channel主要用于读写数据

Selector轮询管理Channel,在多路复用器中为各个管道和状态找到对应处理方法,采用事件驱动的思想来实现的。

(就是开个线程Selector来轮询控制Channel,当Channel有变化的时候,就去判断Channel状态来进行开启新的线程处理具体IO操作)

注意:

  • seletor.select();在Select线程的主循环中是阻塞的,只有来具体的事件才会驱动下去,比如新的连接,Channel有新数据等
  • ServerSocketChannel.accept();是为了接入新的客户端连接到selector

NIO java 启动流程

1)      首先是先创建ServerSocketChannel 对象,和真正处理业务的线程池

2)      然后给刚刚创建的ServerSocketChannel 对象进行绑定一个对应的端口,然后设置为非阻塞

3)      然后创建Selector对象并打开,然后把这Selector对象注册到ServerSocketChannel 中,并设置好监听的事件,监听 SelectionKey.OP_ACCEPT

4)      接着就是Selector对象进行死循环监听每一个Channel通道的事件,循环执行 Selector.select() 方法,轮询就绪的 Channel

5)      从Selector中获取所有的SelectorKey(这个就可以看成是不同的事件),如果SelectorKey是处于 OP_ACCEPT 状态,说明是新的客户端接入,调用 ServerSocketChannel.accept 接收新的客户端。

6)      然后对这个把这个接受的新客户端的Channel通道注册到ServerSocketChannel上,并且把之前的OP_ACCEPT 状态改为SelectionKey.OP_READ读取事件状态,并且设置为非阻塞的,然后把当前的这个SelectorKey给移除掉,说明这个事件完成了

7)      如果第5步的时候过来的事件不是OP_ACCEPT 状态,那就是OP_READ读取数据的事件状态,就去进行IO操作

BIO和NIO区别

  • BIO面向流,NIO面向缓冲
  • BIO阻塞,NIO非阻塞

BIO一个连接一个线程,NIO一个请求一个线程

posted @ 2022-02-23 13:36  xujf  Views(57)  Comments(0Edit  收藏  举报