前言
关于IO模式的区别,网络上的文章一搜一大把,但每次阅读时总觉得相当晦涩而且老容易混淆,俗话说好记性不如烂笔头,所以干脆自己写一篇便于自己理解的文章以此帮助记忆和理解,不对之处还请轻喷,先谢谢!
- 同步阻塞IO(Blocking IO)BIO
- 同步非阻塞IO(Non-blocking IO)
- IO多路复用(IO Multiplexing)注意: 它也是同步的,又叫New IO,即NIO
- 异步IO(Asynchronous IO)AIO
一、何谓阻塞?何谓同步?
如何区别同步IO还是异步IO,是阻塞IO还是非阻塞IO,主要区别是IO过程中其实是存在2个过程:1.发起IO过程 2.实际IO过程,如果过程1是需要等待的,那么就是属于阻塞IO,反之则是非阻塞IO,如果过程2中是需要等待的,那么就是同步IO,反之则是属于异步IO,为啥都是等待的,一个叫阻塞一个叫同步呢?个人理解是这样的:IO过程发生在AB之间,A相当于用户线程或者网络客户端,B相当于系统线程或者网络服务端,AB之间的访问、调用过程分阻塞or非阻塞,但是真正的一个完整的IO过程其实是由C参与的,这个C才是真正IO的主体,相当于操作系统、数据库等,那么B和C之间的存取、读写过程分同步or异步
二、举个栗子
阻塞or非阻塞,这个生活中最好理解的就是你要买东西,_是你自己去买还是让你弟弟去买_,你自己去买就是阻塞,让你弟弟买回来再给你就是非阻塞,你弟弟买的时候你可以干其他事情( 怎么买的你先别管)
同步or异步,还是举上面那个例子,同步IO,是得你自己(阻塞)or你弟弟(非阻塞)不断去京东网站上查询物流到哪里了?到了就你自己(阻塞)or你弟弟(非阻塞)跑去拿,典型的例子就是**京东自提,异步IO呢?就是你网店下好单之后就甭管了,快递员会自动把货送到你或者你弟弟手上,典型的例子就是京东送货上门**
说到这里应该很多同学都应该能瞬间秒懂这几个模式的区别了
上面BIO, NBIO,以及NIO都是同步的IO(后2者只是没有阻塞发起方),只有AIO才是真正异步的IO,Java也是在1.7才开始支持AIO,Tomcat容器在AIO上实现叫APR,基于Native Library实现异步
三、重点谈谈NIO
很早以前Java和Tomcat就支持了BIO,这种模式最简单,但是效率也最差,显而易见大量时间都耗费在了等待IO上,而IO又正好是极其耗费时间的,所以现在基本上都是New IO(NIO) ,AIO由于实现相当复杂还必须有操作系统支持,(据说Netty的AIO实现比NIO效率还慢,所以放弃了,我没详细了解过)所以现在并没有NIO普及,这里重点讨论一下NIO吧,NIO即经典的Reactor模式(Reactor最近是火哦)
好,还是从生活中的例子入手吧,NIO是同步非阻塞+复用链接,你跟你弟弟说:我要买鼠标,然后小姐姐说:弟,我也要!,弟弟说:好,下单!,你跟小姐姐去逛街去了,你弟弟就不停的隔段时间查询下网站,突然发现小姐姐的快递已经到家了,马上通知小姐姐:姐!你快递到了!,小姐姐立刻马上结束逛街回到家领快递,1个小时后你弟弟又告诉你说你的快递到了,你又立刻拿了快递,结束。
从这个例子可以看出,你弟弟其实是一个蛮重要的角色,对!没错,他就是NIO模式中的Reactor,负责查询物流信息(select channel and read socket),发现socket可读之后通知用户线程读取数据,所以从tomcat开启NIO后吞吐量大增的现象就可以发现,每个请求就像一个个的小姐姐,tomcat里有个小弟弟在轮训等待IO结果并负责通知小姐姐结果。