NIO

什么是 NIO

java NIO是在JDK1.4 开始使用的,它既可以说成新 I/O (new io),也可以说成非阻塞 I/O(no-blocking io),NIO弥补了原来 I/O 的不足,它在标准java代码中提供了高速的 、面向块的 I/O 。

和BIO的区别

BIO:一个连接一个线程、面向流、流是阻塞的(当一个线程调用read(),或者write()时,该线程被阻塞,直至数据被读或者写完,期间该线程不能干任何事情)
NIO:一个请求一个线程、面向缓冲区、非阻塞(事件驱动,客户端发送的连接请求都会注册到多路复用器上,多路复用
器轮询到连接有 I/O 请求时才启动一个线程进行处理)

NIO 三大核心组件

Selector(选择器)

也可以称为 “ 轮询代理器”、“事件订阅器”等。
java NIO的选择器允许一个单独线程来监视多个输入管道,你可以注册多个通道使用一个选择器,然后使用一个单独的线程来操作这个选择器,进而选择通道:这些通道里已经有可以处理的输入,或者选择已准备写入的通道。这种选择机制,使得一个 单独的线程很容易来管理多个通道。
应用程序将向 Selector 对象注册需要它关注的 Channel,以及具体的某一个 Channel 会 对哪些 IO 事件感兴趣。Selector 中也会维护一个“已经注册的 Channel”的容器。

Channel (管道)

管道,建立的一个应用程序和操作系统交互事件、传递内容的管道(连接操作系统),既然是和操作系统进行内容传递,那么说明应用程序可以通过管道读取数据,也可以通过管道向操作系统写数据,而且可以同时进行读写。

  1. 所有被 Selector(选择器)注册的通道,只能是继承了 SelectableChannel 类的子类。
  2. ServerSocketChannel:应用服务器程序的监听通道。只有通过这个通道,应用程序才 能向操作系统注册支持“多路复用 IO”的端口监听。同时支持 UDP 协议和 TCP 协议。
  3. ScoketChannel:TCP Socket 套接字的监听通道,一个 Socket 套接字对应了一个客户 端 IP:端口 到 服务器 IP:端口的通信连接。

buffer 缓冲区(下篇单独介绍)

在这里插入图片描述
Buffer 用于和 NIO 通道进行交互。数据是从通道读入缓冲区,从缓冲区写入到通道中的。 以写为例,应用程序都是将数据写入缓冲,再通过通道把缓冲的数据发送出去,读也是一样, 数据总是先从通道读到缓冲,应用程序再读缓冲的数据。 缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存( 其实就是数组)。 这块内存被包装成 NIO Buffer 对象,并提供了一组方法,用来方便的访问该块内存。

SelectionKey

什么是SelectionKey

SelectionKey是一个抽象类,表示selectableChannel在Selector中注册的标识.每个Channel 向 Selector 注册时,都将会创建一个 SelectionKey。SelectionKey 将 Channel 与 Selector 建立了 关系,并维护了 channel 事件。
可以通过 cancel 方法取消键,取消的键不会立即从 selector 中移除,而是添加到 cancelledKeys 中,在下一次 select 操作时移除它,所以在调用某个 key 时,需要使用 isValid 进行 校验。

SelectionKey 类型和就绪条件

在向 Selector 对象注册感兴趣的事件时,JAVA NIO 共定义了四种:OP_READ、OP_WRITE、 OP_CONNECT、OP_ACCEPT(定义在 SelectionKey 中),分别对应读、写、请求连接、接受 连接等网络 Socket 操作。

操作类型就绪条件及说明
OP_READ当操作系统读缓冲区有数据可读时就绪。并非时刻都有数据可读,所 以一般需要注册该操作,仅当有就绪时才发起读操作,有的放矢,避免浪 费 CPU。
OP_WRITE当操作系统写缓冲区有空闲空间时就绪。一般情况下写缓冲区都有空 闲空间,小块数据直接写入即可,没必要注册该操作类型,否则该条件不 断就绪浪费 CPU;但如果是写密集型的任务,比如文件下载等,缓冲区很 可能满,注册该操作类型就很有必要,同时注意写完后取消注册。
OP_CONNECT当 SocketChannel.connect()请求连接成功后就绪。该操作只给客户端 使用。
OP_ACCEPT当接收到一个客户端连接请求时就绪。该操作只给服务器使用。

服务端和客户端分别感兴趣的类型

ServerSocketChannel 和 SocketChannel 可以注册自己感兴趣的操作类型,当对应操作类 型的就绪条件满足时 OS 会通知 channel,
下表描述各种 Channel 允许注册的操作类型,Y 表 示允许注册,其中服务器 SocketChannel 指由服务器 ServerSocketChannel.accept()返回的对象。

项目OP_READOP_WRITEOP_CONNECTOP_ACCEPT
服务器 ServerSocketChannelY
服务器 SocketChannelYY
客户端 SocketChannelYYY
  1. 服务器启动 ServerSocketChannel,关注 OP_ACCEPT 事件
  2. 客户端启动 SocketChannel,连接服务器,关注 OP_CONNECT 事件
  3. 服务器接受连接,启动一个服务器的 SocketChannel,这个 SocketChannel 可以关注 OP_READ、OP_WRITE 事件,一般连接建立后会直接关注 OP_READ 事件
  4. 客户端这边 SocketChannel 发现连接建立后,可以关注 OP_READ、OP_WRITE 事件,一般是需要客户端需要发送数据了才关注 OP_READ 事件
  5. 连接建立后客户端与服务器端开始相互发送消息(读写),根据实际情况来关注OP_READ、 OP_WRITE 事件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值