Java IO 入门之NIO等框架性能了解

nio

同步: 自己亲自出马持银行卡到银行取钱(使用同步IO时,Java自己处理IO读写)。

异步: 委托一小弟拿银行卡到银行取钱,然后给你(使用异步IO时,Java将IO读写委托给OS处理,需要将数据缓冲区地址和大小传给OS(银行卡和密码),OS需要支持异步IO操作API)。

阻塞: ATM排队取款,你只能等待(使用阻塞IO时,Java调用会一直阻塞到读写完成才返回)。

非阻塞: 柜台取款,取个号,然后坐在椅子上做其它事,等号广播会通知你办理,没到号你就不能去,你可以不断问大堂经理排到了没有,大堂经理如果说还没到你就不能去 (使用非阻塞IO时,如果不能读写Java调用会马上返回,当IO事件分发器会通知可读写时再继续进行读写,不断循环直到读写完成)。

一、IO NIO AIO

io、nio、aio的区别,类似于resin、apache、nginx在io处理上的区别,从多线程互不干扰的阻塞式执行(resin),到轮询式的同步非阻塞式(apache),再到异步非阻塞式(nginx)。
现在这三种io都在jdk中予以了支持。

  1. IO (BIO)
    同步并阻塞,服务器实现模式为一个连接一个线程,每个线程亲自处理io并且一直等待io的完成,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。
    IO的局限:IO是面向流的,阻塞式的,串行的一个过程。对每一个客户端的socket连接,IO都需要一个线程来处理,而且在此期间,这个线程一直被占用,直到socket关闭。在这期间,tcp的连接、数据的读取、数据的返回都是被阻塞的。也就是说这期间大量的浪费了cpu的时间片和线程占用的内存资源。
    每建立一个Socket连接时,同时创建一个新线程对该Socket进行单独通信(采用阻塞的方式通信)。这种方式具有很高的响应速度,并且控制起来也很简单,在连接数较少的时候非常有效,但是如果对每一个连接都产生一个线程的无疑是对系统资源的一种浪费,如果连接数较多将会出现资源不足的情况。

  2. NIO (new IO) 从jdk1.4开始
    同步非阻塞,服务器实现模式为一个请求一个线程,每个线程亲自处理io,但有另外的线程轮询检查是否io准备完毕,不必等待io完成,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。
    **NIO则是面向缓冲区的,非阻塞式的,基于选择器的,用一个线程来轮询监控多个数据传输通道,哪个通道准备好了(即有了一组可以处理的数据),就处理哪个通道。 **
    服务器端保存一个Socket连接列表,然后对这个列表进行轮询,如果发现某个Socket端口上有数据可读时(读就绪),则调用该socket连接的相应读操作;如果发现某个 Socket端口上有数据可写时(写就绪),则调用该socket连接的相应写操作;如果某个端口的Socket连接已经中断,则调用相应的析构方法关闭 该端口。这样能充分利用服务器资源,效率得到了很大提高。

  3. AIO (Asynchronous io、NIO.2) 从jdk1.7开始
    异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理,每个线程不必亲自处理io,而是委派os来处理,并且也不需要等待io完成了,如果完成后,os会通知的。
    采用linux的epoll模型。

结论

在连接数不多的情况下,传统IO编写容易、方便使用。但是随着连接数的增多,问题传统IO就不行了。因为传统IO处理每个连接都要消耗一个线程,而程序的效率当线程数不多时是随着线程数的增加而增加,但是到一定的数量之后,是随着线程数的增加而减少。所以传统阻塞式IO的 瓶颈在于不能处理过多的连接。

非阻塞式IO的出现的目的就是为了解决这个瓶颈。而非阻塞式IO是怎么实现的呢?非阻塞IO处理连接的线程数和连接数没有联系,也就是说处理10000个 连接非阻塞IO不需要10000个线程,你可以用1000个也可以用2000个线程来处理。因为非阻塞IO处理连接是异步的。当某个连接发送请求到服务 器,服务器把这个连接请求当作一个请求"事件",并把这个"事件"分配给相应的函数处理。我们可以把这个处理函数放到线程中去执行,执行完就把线程归还。 这样一个线程就可以异步的处理多个事件。而阻塞式IO的线程的大部分时间都浪费在等待请求上了。

然后NIO的非阻塞,需要一直轮询,也是一个比较耗资源的,所以出现AIO 。

BIO、NIO、AIO适用场景

** BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。**

**NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。 **

AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。

**ps:AIO、NIO是基于IO的,并不是取代IO的意思。 **

二、NIO的框架

IO的概念:

  1. 就IO而言:概念上有5中模型:blocking I/O,nonblocking I/O,I/O multiplexing (select and poll),signal driven I/O (SIGIO),asynchronous I/O (the POSIX aio_functions)。
  2. 然后呢 不同的操作系统对上述模型支持不同: unix支持io多路复用,不同系统叫法不同 :freebsd里面叫 kqueue;linux 是epoll。而windows: 2000的时候就诞生了IOCP支持最后一种异步I/O
  3. java是一种跨平台语言,为了支持异步IO,诞生了nio,Java1.4引入的NIO 1.0是基于I/O复用的。在各个平台上会选择不同的复用方式。Linux用的epoll,BSD上用kqueue,Windows上应该是重叠I/O(肯定不是IOCP)。
  4. 基于jdk的nio ,不同公司出了一堆框架:apache mina ,jboss的netty,sun的grizzly。 这些都是直接封装传输层的tcp/udp。

nio直接使用比较难用,所以有了netty等针对网络io部分(tcp/udp-传输层)的封装(nio也有非网络io部分),为了使nio更易用。 ** netty等只是一个nio框架,不需要web容器的额外支持,也就是说不限定web容器。**

3个NIO框架是:

  1. Mina
    Mina(Multipurpose Infrastructure for Network Applications) 是 Apache组织一个较新的项目,它为开发高性能和高可用性的网络应用程序提供了非常便利的框架。当前发行的 Mina 版本2.04支持基于 JavaNIO 技术的 TCP/UDP 应用程序开发、串口通讯程序,Mina 所支持的功能也在进一步的扩展中。目前,正在使用Mina的应用包括:Apache Directory Project、AsyncWeb、AMQP(Advanced MessageQueuing Protocol)、RED5 Server(Macromedia? FlashMedia RTMP)、ObjectRADIUS、 Openfire等等。
  2. Netty
    Netty是一款异步的事件驱动的网络应用框架和工具,用于快速开发可维护的高性能、高扩展性协议服务器和客户端。也就是说,Netty是一个NIO客户端/服务器框架,支持快速、简单地开发网络应用,如协议服务器和客户端。它极大简化了网络编程,如TCP和UDP套接字服务器。
  3. Grizzly
    Grizzly是一种应用程序框架,专门解决编写成千上万用户访问服务器时候产生的各种问题。使用JAVANIO作为基础,并隐藏其编程的复杂性。容易使用的高性能的API。带来非阻塞socketd到协议处理层。利用高性能的缓冲和缓冲管理使用高性能的线程池。

Servlet3.0 vs NIO

servlet3.0是一个规范、或者协议,可以用IO实现,也可以用NIO实现,而NIO则只是一种技术实现。一个是架构,一个是具体技术。

  • 相同:
    都提供了异步功能。
  • 不同:
    • jdk的nio直接使用比较难用,所以有了netty这些针对网络io部分(tcp/udp-传输层)的封装(nio也有非网络io部分),为了使nio更易用而已。
  • servlet3.0是另外一个东西,不是对io的封装,而是javaee6众多规范中的一个。但凡javaee6的实现(或者像tomcat这种web容 器部分的实现),都会支持servlet3.0,servlet理论上可以支持多种应用层协议(不单单只是http),而servlet3.0以后提供的 异步特性与javase提供的nio或aio无直接关系,就是使用bio一样可以实现servlet3.0中提供的异步特性。

可以说NIO的异步是直接处理的更底层的IO,而Servlet3.0的异步指的是上层的请求响应的异步
转自:http://qindongliang.iteye.com/blog/2017278

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容