网络通信-NIO

BIO、NIO、AIO区别

BIO是同步阻塞IO
NIO是同步非阻塞
AIO是异步非阻塞,这个用的少,且操作系统支持力度的不够完善。

了解它们区别,必须要搞清楚 同步、异步 与 阻塞、非阻塞 两组的关系。

同步、异步是相对线程运行任务情况以及对用户的感知区分的,所谓同步就是线程接受任务必须把任务运行完成之后才反馈用户结果; 所谓异步就是线程接受到任务后立即反馈给用户状态,然后自己默默的后台运行任务,运行完成之后再把结果通知给用户。
IO同步还是异步主要看IO线程读写操作是同步还是异步。这里BIO、NIO都是同步,AIO是异步。

阻塞、非阻塞是相对于调用者(IO操作线程)在IO读写操作是否一直阻塞(一直等)。IO读写数据底层是操作系统帮我们进行的,本质要看操作系统IO读写是否阻塞。操作系统是否阻塞就要看应用选择哪种操作系统的IO模型。

同步异步与阻塞非阻塞之间的关系有点依赖操作系统的IO操作模型决定。操作系统是底层代码设计肯定会影响应用层代码设计。了解操作IO模型,能够更好理解BIO,NIO,AIO。

liunx 5种 IO模型

  1. 阻塞IO

最传统的一种IO模型,系统读写数据过程中会发生阻塞现象 且 IO读写线程也是同步(内核态数据 与用户态数据拷贝)。即用户线程等数据读写。

  1. 非阻塞IO

系统在读写数据过程中不会阻塞,也就是说不管有没有数据都会返回,如果想要读取到有效数据,就需要用户线程不停循环读取所要的数据。但是 IO读写线程也是同步。

  1. IO多路复用模型
    IO多路复用我感觉是一种设计模式,就是单独开一个进程去监控所有的IO操作事件,如果有事件发生就通知其他进程去相应的IO操作。Linux下包括了三种,select、poll、epoll,抽象来看,他们功能是类似的,首先都会对一组文件描述符进行相关事件的注册,然后阻塞等待某些事件的发生,最后把事件通知应用线程读写操作。但是一样 IO读写线程也是同步。

  2. 信号驱动IO模型
    有点和IO多路复用技术差不多,当有事件发生时发送一个信号通知给应用程序,然后应用程序读取数据。但是一样 IO读写线程也是同步。

  3. 异步IO模型
    有点和信号驱动IO模型,但会多做一步IO读写操作(准确的说是内核态数据 与用户态数据拷贝),然后再通知应用程序,这时应用程序不用再去读或写操作。因为这里已经完成数据态的拷贝,所以这里IO读写操作是异步的。

所以通过对操作系统IO模型了解可以反推BIO,NIO,AIO,上面
阻塞IO当然是IO同步的。 = BIO
非阻塞IO也是IO同步。 =NIO
同理IO多路复用和信号驱动IO也是同步IO,但是是事件驱动设计并不会阻塞线程。 =NIO
只有异步IO是完全完成了数据的拷贝之后才通知程序进行处理,没有阻塞的数据读写过程。=AIO

NIO

这里主要说的java NIO的实现。本质对操作系统的IO多路复用技术实现的封装。
NIO特点:

  1. 事件驱动模型、单线程处理多任务
  2. 非阻塞

NIO主要组件:

  1. channel
    channle 可以简单理解为 客户端与服务端 连接的一条通道,该通道是双向。

  2. buffer
    Buffer 叫数据缓冲区,是与 Channel 进行交互,数据是从 Channel 读入缓冲区,从缓冲区写入 Channel 中的。我们数据都是与Buffer进行交互。

  3. selector

public abstract class AbstractSelector extends Selector{}
这个对IO多路复用接口进行封装,一个selector可以管理多个channl。主要有以下方法:
a. open() 方法用来 创建一个 Selector 对象
b. register() 方法 向多路复用器器注册通道,可以监听的事件类型:读、写、连接、accept。返回SelectionKey. 这个key 与 channel 对应绑定关系。
c. deregister() 方法 取消绑定关系。

Selector 在 Linux 的实现类是 EPollSelectorImpl,委托给 EPollArrayWrapper 实现,其中三个native 方法是对 epoll 的封装,而 EPollSelectorImpl. implRegister 方法,通过调用 epoll_ctl
向 epoll 实例中注册事件,还将注册的文件描述符(fd)与 SelectionKey 的对应关系添加到
fdToKey 中,这个 map 维护了文件描述符与 SelectionKey 的映射。

Netty

首先 Netty!=NIO,Netty是一个高性能,异步事件驱动NIO框架,简单的说对JAVA NIO进行封装好了的开发框架,开箱即用,内置很多编解码器以及handler。这里说的异步是Netty 框架里所有的操作是异步的比如:bind(),write()等方法,但是读取数据的IO线程还是同步的。

Netty线程模型

Netty 线程模型就是标准的Reactor 模型,基于操作系统的IO多路复用模型实现的。
支持三种线程 Reactor模型:单线程模型,多线程模型,主从多线程模型。(度娘一下很多介绍)

Netty优势

基于Netty框架,比原生开发NIO,要方便很多。首先1.Netty 解决JDK NIO 中的 epoll 模型空轮询造成CPU100%的bug。造成空循环本质是由于操作系统EPOLL 抛出其他的事件,导致Selector不停的遍历获取响应事件。Netty解决方法是:如果循环了多次,就新建一个selector,将原来的key-channel绑定关系,移动到新的selector上。

其次主要有

  1. 提供很多编码器和解码器,对TCP的自动粘包/分包自动化处理。
  2. 提供心跳检测机制。
  3. 可以循环利用byteBuf,也就是内存池,以及还支持使用堆外内存分配方式。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值