NIO实现原理

本人很懒,只想说重点。


在读之前你应该知道什么是BIO,就是Blocking IO,阻塞式IO。这或许是大家最或者说是老一代程序员最熟悉的网络IO模型,服务端需要为每个客户端的连接创建一个线程去处理该连接,一旦客户端达到一定量级,这时服务端是承受不起的。


NIO提出了一个新的概念,事实上从编程语言来说,这个概念早已被支持。但像我这样的java工程师好像是在jdk1.4之后才被支持的(具体我忘了,这并不重要)。NIO最核心的是select的多路复用概念,它使用唯一一个线程去处理select方法。每当有客户端有连接、读、写等各种请求来到时,select方法就能拿到这些请求的客户端然后交与下游线程(或线程池)来处理,这样一来,对比之前BIO每个连接一个线程的方式,NIO有了明显优势。


NIO是怎么实现呢?当然它需要操作系统的支持(任何底层服务的实现最终都要通过操作系统来实现),拿Linux来说吧,它最终用epoll来实现NIO,但在2.6之前linux是不支持epoll的。

那么epoll是如何进化过来的呢?以下是重点:

1、在最开始的时候,OS使用一个程序专门无循环地去读基于这个socket的IO流,来确保是否有有客户端请求过来。这肯定会造成CPU浪费,因为大部分时间客户端可能并未发启任请求。

2、OS试图去优化这种不良现象,于是它优化了select方法,该方法等待到真正有客户端请求过来时才返回(注意,这步很重要,它将1中的非阻塞轮询变成了阻塞式),这看起来不错,但事实上在这个阶段,服务端只是知道了的确有IO流过来,但是它并不知道到底是由哪些客户端请求过来的,所以它只能不停地轮询那些连接到服务端的客户端,假设客户端连接数是N,那这个轮询的复杂度就是0(N),一旦客户端连接数超过某个量级,性能会受到很大影响。

3、epoll的到来,epoll对第二阶段进一步优化,当select方法返回时,它只返回那些真正就IO交互的请求,事实上这步操作能让后续的处理从本来的0(N)降到0(1),虽然从理论上这个算法复杂度不科学,但如果细想一下在某个时间段内服务端接收到的请求只会是那么几个客户端。


有些人盲目选择NIO,但它们忽略了BIO的优势,从上面的分析来看,NIO并不是实时的(也许可以称为准实时),它受select的调用频率。但BIO却是时实的,以我的经验,对于一个少于或等于1K个连接数并且以时实性为优先的server来说,选取BIO的方式是一种合理并且高效的方式,但如果连接数一旦超越这个量级并可能高出很多时那就需要NIO的出场了。


事实上AIO模型正在一步步被实现,我坚信AIO迟早会被实现,到那时毫无疑问这是最好的网络IO模型。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值