基于NIO模型的Java Socket传统编程

     这张是2014年在拉卜楞寺拍摄的,僧人们下早课。红袍加身不可脱,这是其中一位僧人给我和基友担当向导时说的,他7岁从青海来学习佛法,因为家里还有一个哥哥,两个男孩的话弟弟会被送去佛学院出家,所以他被送出来了,现在已经26了,将来可以选择回家乡附近的寺庙工作,也可以留在这所佛学院或寺里继续工作,其他记不太住了,只记得当时我用的iphone4,他用的iphone5s。

   

王皓的GitHub:https://github.com/TenaciousDWang

 

      在上一篇文章中,我们说的是基于BIO模型下的Java Socket传统编程,其中我们提到了很多关于BIO的弊病。

 

      现在,我们来说一下在Java中基于NIO模型的Socket编程,NIO在有的文章中叫做Non-block Input&Output Model,也有文章叫做New Input/Output Model,总之就是为了优化BIO中的问题而提出的新的解决方案。

 

      这里引用一下《Netty in action》里面的插图,我们看到上图就是BIO模型下一个线程管理一个Socket。

 

       NIO模型中,把一堆线程都交给一个Selector来管理,使用一个单一线程便可以处理多个并发连接。

        

      我们直接举一个现实中通俗的例子来讲,在一个商场内里,顾客需要导购员介绍商品或提供服务,现在有100个顾客,有两种方案可以解决这个问题:

 

     1.每个顾客配一个导购员。每个导购员跟着随时应对顾客提出的问题,这就是传统IO模型,一个连接对应一个线程。

 

      2.商场里面只放5个导购员。每个导购员应对20个顾客,一个导购员一直轮训这20个顾客,有需求就来解决,这就是 NIO 模型,一堆顾客都注册到同一个导购员,对应的就是一堆连接都注册到一个线程,然后批量轮询,一个线程可以管理一批连接,相对于 IO 模型中一个线程对应一条连接,这就是 NIO 模型解决线程资源受限的方案,线程资源消耗大幅减少。

  

     上面的例子非常简洁明了,BIO模型不适用于socket连接数巨大的情况。在NIO模型下的导购员就是其selector的概念,一个线程管理多条连接,大大减少了对资源的浪费,同时NIO模型中线程数量的大量减少,提升了线程切换的效率,也就是提高的通信效率。

 

      传统IO的读写是使用流来读写,需要自己来缓存数据,NIO采用了Buffer读写,我们只需要移动指针即可。

 

      虽然上述说了一大堆NIO模型下Socket编程的好处,但是在现在的网上和各类书籍中却不建议使用原生java的nio包进行编程,大概总结原因如下:

 

  1. NIO编程中需要了解很多的概念,且编程复杂,编程方式不友好。
  2. NIO编程中你需要自己实现一个线程模型,很多工具类都要你自己实现比如拆包等。
  3. NIO底层由epoll实现,该实现饱受诟病的空轮询bug会导致cpu飙升100%到现在还存在这个BUG。
  4. NIO编程中代码量,业务逻辑非常庞大后,自己写的NIO很容易出现各类BUG,维护成本较高。

 

      这里只讲NIO模型下Socket编程的原理,不再列出举例代码,网上很多关于NIO的资料感兴趣可以查阅。

 

        尽管已经有许多直接使用Java NIO API 的应用程序被构建了,但是要做到如此正确和安全并不容易。特别是,在高负载下可靠和高效地处理和调度I/O 操作是一项繁琐而且容易出错的任务,

最好留给高性能的网络编程专家——Netty。

 

      Netty是Java网络编程领域的卓越框架。

     最后推荐一本书:《Netty in action》。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值