为了账号安全,请及时绑定邮箱和手机立即绑定

谈谈传统BIO网络编程模型的局限性与NIO

标签:
Java

先来看看我们的server端:

创建一个serversocket,进行监听,每来一个客户端,就启动一个新启动为其服务:

private void createListenSocket() {
       //如果创建监听socket的时候发生异常,将会隔WAIT_TIME毫秒重试,直到成功
       while (true){
           try {
               serverSocket = new ServerSocket(LISTEN_PORT);
               Log.info("创建监听socket成功,正在监听...");
               break;
           } catch (IOException e) {
               Log.error("创建监听socket失败,原因:"+e.getMessage()+WAIT_TIME+"ms后重建");
               ThreadUtils.sleep(WAIT_TIME);
           }
       }
   }
private void listen() throws IOException {
       Socket socket = null;
       //启动一个死循环来监听连接本服务器的socket
       while ((socket = server.accept()) != null) {
           // 来访客户记录到服务器:
           Destination destination = new Destination();
           destination.setSocket(socket);
           server.newDestination(destination);
           //启动一条子线程来处理连接本服务器的socket消息收发
           new SubListenThread(destination,server).start();

       }
   }

以上代码来自我半年前编写的一个远控程序服务端。在这个模型当中,服务端线程与客户端线程是1:1的关系,也就是说有多少个客户端,服务端就得创建多少个线程。

在java当中,创建线程的代价是很大的。如果有几千个客户端,这个程序是撑不住的。

那么像旺旺这种在线量可以达到几百万的应用,在单个机器上,势必要用一种比BIO更好的编程模型来实现。

那么NIO就可以解决这种应用场景。

关于NIO的教程,网上有非常多的详细教程,在这里就不赘述。就简单说说NIO编程模型:

首先,我们有几个基本概念:

1.channel 大家可以把它想象成stream,只不过我们可以通过channel进行双工通信,也就是能读又能写。

2.buffer 可以看做是一段缓存,我们能通过这么一段缓存对channel进行读写。

3.selector 中文直接翻译过来就是选择器,因为在NIO当中,我们不通过传统的一个线程处理一个客户端,而是通过轮询的方式知道哪些客户端可读、可连接,从而实现1:n的模型。

那么NIO的编程模型如下:

通过一个selector,客户端会连接到这个selector,我们可以通过一个死循环不断地轮询selector有哪些客户端,然后一旦监听到可读或者可连接事件,我们就进行相应的业务逻辑处理,该读读,该写写。

以下为一个简单多人聊天室部分源码:

5cc137370001df5705750547.jpg

5cc137380001949d08310575.jpg

看起来还是很复杂的,至少比传统的BIO通信模型复杂。

使用原生的nio api进行编程很难,而且这玩意还有bug,据说在1.8以上版本仍存在空轮询BUG,会让CPU飙到100%。

所以说,如果可以的话,尽量使用一些第三方框架,比如netty。


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消