这张是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包进行编程,大概总结原因如下:
这里只讲NIO模型下Socket编程的原理,不再列出举例代码,网上很多关于NIO的资料感兴趣可以查阅。
尽管已经有许多直接使用Java NIO API 的应用程序被构建了,但是要做到如此正确和安全并不容易。特别是,在高负载下可靠和高效地处理和调度I/O 操作是一项繁琐而且容易出错的任务,
最好留给高性能的网络编程专家——Netty。
Netty是Java网络编程领域的卓越框架。
最后推荐一本书:《Netty in action》。