聊聊BIO,NIO,AIO的区别


聊聊BIO、NIO、AIO的区别

举例说明

海底捞很好吃,但是经常要排队。我们就以生活中的这个例子进行讲解。

  • A顾客去吃海底捞,就这样干坐着等了一小时,然后才开始吃火锅。(BIO)

  • B顾客去吃海底捞,他一看要等挺久,于是去逛商场,每次逛一会就跑回来看有没有排到他。于是他最后既购了物,又吃上海底捞了。(NIO)

  • C顾客去吃海底捞,由于他是高级会员,所以店长说,你去商场随便玩吧,等下有位置,我立马打电话给你。于是C顾客不用干坐着等,也不用每过一会儿就跑回来看有没有等到,最后也吃上了海底捞(AIO)

BIO(Blocking IO)

BIO.png

  • 早期传统的IO模型(JDK1.4之前),同步阻塞模式
  • 线程发起IO请求后,一直阻塞IO,直到缓冲区数据就绪后再进入下一步操作
  • 网络间通信是一请求一应答方式的,若每个请求都需要新建一个线程来专门处理,那么在高并发场景下,机器资源很快就会被耗尽

NIO (New IO)

NIO(Non-Blocking IO)

  • 同步非阻塞模式
  • 线程发起IO请求后,立即返回
  • 非阻塞模式下,用户线程不必原地等待IO缓冲区,可以去做其他操作
  • 它需要定时轮询检查IO缓冲区数据是否就绪

NIO.png

  • NIO+IO多路复用技术
  • 普通的NIO是线程轮询查看一个IO缓冲区是否就绪,而Java中的new IO指的是线程轮询地去查看一堆IO缓冲区中哪些就绪(多路复用思想)
  • IO多路复用模型中,将检查IO数据是否就绪的任务,交给系统级别的select/epoll模型,由系统进行监控,减轻用户线程负担
  • NIO主要由buffer、channel、selector三种技术整合
  • 通过零拷贝的buffer取得数据,每个客户端通过channel在select(多路复用器)上进行注册。
  • 服务端不断轮询channel来获取客户端的信息
  • channel上的四种状态标识,根据标识进行后续操作
    • connect
    • accept(阻塞)
    • read
    • write
  • 因此一个服务端可以接收无限多的channel,不需要新开一个线程,进而大大提升性能

AIO

  • AIO是真正意义上的异步非阻塞IO模型
  • 上述NIO实现中,需要用户线程定时轮询,去检查IO缓冲区数据是否就绪,占用应用程序线程资源,其实轮询相当于还是阻塞的,并非真正解放当前线程,因为它还是需要去查询哪些IO就绪。而真正的理想的异步非阻塞IO应该让内核系统完成,用户线程只需要告诉内核,当缓冲区就绪后,通知我或者执行我交给你的回调函数
  • AIO可以做到真正的异步的操作,但实现起来比较复杂,支持纯异步IO的操作系统非常少,目前也就windows是IOCP技术实现了,而在Linux上,底层还是是使用的epoll实现的

总结

并发连接数不多时采用BIO,因为它编程和调试都非常简单,但如果涉及到高并发的情况,应选择NIO或AIO,更好的建议是采用成熟的网络通信框架Netty

BIONIOAIO
是否阻塞阻塞非阻塞非阻塞
同步/异步同步同步异步
性能一般
客户端与线程比1:1N:1N:0
吞吐量
可靠性非常差
调试难度简单复杂复杂
使用场景连接数较小且固定架构连接数多且连接较短(轻操作架构),如聊天服务器连接数多且连接较长(重操作架构),如相册服务器
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值