NIO网络编程

一、NIO概述

NIONon-blocking I/O,在Java领域,也称为New I/O),这个库是在JDK1.4中才引入的,是一种同步非阻塞的I/O模型,也是I/O多路复用的基础,已经被越来越多地应用到大型应用服务器,成为解决高并发与大量连接、I/O处理问题的有效方式。

那么NIO的本质是什么样的呢?它是怎样与事件模型结合来解放线程、提高系统吞吐的呢?

本文会从传统的阻塞I/O和线程池模型面临的问题讲起,然后对比几种常见I/O模型,一步步分析NIO怎么利用事件模型处理I/O,解决线程池瓶颈处理海量连接,包括利用面向事件的方式编写服务端/客户端程序。最后延展到一些高级主题,如ReactorProactor模型的对比、Selector的唤醒、Buffer的选择等。

注:本文的代码都是伪代码,主要是为了示意,不可用于生产环境。

 

二、IO模型

1.阻塞IO模型

 

传统BIO模型分析

让我们先回忆一下传统的服务器端同步阻塞I/O处理(也就是BIOBlocking I/O)的经典编程模型:

{

 ExecutorService executor =Excutors.newFixedThreadPollExecutor(100);//线程池

 

 ServerSocket serverSocket = newServerSocket();

 serverSocket.bind(8088);

 while(!Thread.currentThread.isInturrupted()){//主线程死循环等待新连接到来

 Socket socket =serverSocket.accept();

 executor.submit(newConnectIOnHandler(socket));//为新的连接创建新的线程

}

 

class ConnectIOnHandler extends Thread{

   private Socket socket;

   public ConnectIOnHandler(Socketsocket){

      this.socket = socket;

   }

   public void run(){

     while(!Thread.currentThread.isInturrupted()&&!socket.isClosed()){ 死循环处理读写事件

         String someThing =socket.read()....//读取数据

         if(someThing!=null){

            ......//处理数据

            socket.write()....//写数据

         }

 

     }

   }

}

这是一个经典的每连接每线程的模型,之所以使用多线程,主要原因在于socket.accept()socket.read()socket.write()三个主要函数都是同步阻塞的,当一个连接在处理I/O的时候,系统是阻塞的,如果是单线程的话必然就挂死在那里;但CPU是被释放出来的,开启多线程,就可以让CPU去处理更多的事情。其实这也是所有使用多线程的本质:

1.利用多核

2.I/O阻塞系统,但CPU空闲的时候,可以利用多线程使用CPU资源

现在的多线程一般都使用线程池,可以让线程的创建和回收成本相对较低。在活动连接数不是特别高(小于单机1000)的情况下,这种模型是比较不错的,可以让每一个连接专注于自己的I/O并且编程模型简单,也不用过多考虑系统的过载、限流等问题。线程池本身就是一个天然的漏斗,可以缓冲一些系统处理不了的连接或请求。

不过,这个模型最本质的问题在于,严重依赖于线程。但线程是很""的资源,主要表现在:

1.线程的创建和销毁成本很高,Linux这样的操作系统中,线程本质上就是一个进程。创建和销毁都是重量级的系统函数。

2.线程本身占用较大内存,像Java的线程栈,一般至少分配512K1M的空间,如果系统中的线程数过千,恐怕整个JVM的内存都会被吃掉一半。

3.线程的切换成本是很高的。操作系统发生线程切换的时候,需要保留线程的上下文,然后执行系统调用。如果线程数过高,可能执行线程切换的时间甚至会大于线程执行的时间,这时候带来的表现往往是系统load偏高、CPU sy使用率特别高(超过20%以上),导致系统几乎陷入不可用的状态。

4.容易造成锯齿状的系统负载。因为系统负载是用活动线程数或CPU核心数,一旦线程数量高但外部网络环境不是很稳定,就很容易造成大量请求的结果同时返回,激活大量阻塞线程从而使系统负载压力过大。

所以,当面对十万甚至百万级连接的时候,传统的BIO模型是无能为力的。随着移动端应用的兴起和各种网络游戏的盛行,百万级长连接日趋普遍,此时,必然需要一种更高效的I/O处理模型。

 

 

2.非阻塞IO模型

 

3.IO复用模型

 

4.信号驱动IO

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值