Java NIO:浅析I/O模型

  • 时间:
  • 浏览:15

  当用户tcp连接发出IO请求前一天,内核会去查看数据是不是 就绪,机会这麼 就绪就会守候数据就绪,而用户tcp连接就会指在阻塞具体情况,用户tcp连接交出CPU。当数据就绪前一天,内核会将数据拷贝到用户tcp连接,并返回结果给用户tcp连接,用户tcp连接才解除block具体情况。

参考资料:

  我们都先来看一下同步IO和异步IO的定义,在《Unix网络编程》一书中对同步IO和异步IO的定义是曾经的:

  异步IO模型才是最理想的IO模型,在异步IO模型中,当用户tcp连接发起read操作前一天,立刻就才能结束英语 去做其它的事。而另一方面,从内核的深度图,当它受到有另有1个asynchronous read前一天,它会立刻返回,说明read请求机会成功发起了,或者不必对用户tcp连接产生任何block。或者,内核会守候数据准备完成,或者将数据拷贝到用户tcp连接,当你这些切都完成前一天,内核会给用户tcp连接发送有另有1个信号,告诉它read操作完成了。也太多用户tcp连接完整性不时要实际的整个IO操作是怎样进行的,只时要先发起有另有1个请求,当接收内核返回的成功信号时表示IO操作机会完成,才能直接去使用数据了。

这段代码是五种典型的异步,fun1的执行不必影响到fun2的执行,或者fun1和fun2的执行不必原因 其后续的执行过程指在暂时的守候。

  这太多阻塞和非阻塞的区别。也太多说阻塞和非阻塞的区别关键在于当发出请求有另有1个操作时,机会条件不满足,是会经常守候还是返回有另有1个标志信息。

  前面五种IO模型实际上都属于同步IO,这麼最后五种是真正的异步IO,机会无论是多路复用IO还是信号驱动模型,IO操作的第有另有1个阶段完会 引起用户tcp连接阻塞,也太多内核进行数据拷贝的过程完会 让用户tcp连接阻塞。

  通常来说,IO操作包括:对硬盘的读写、对socket的读写以及外设的读写。

  不过要注意的是,多路复用IO模型是通过轮询的措施来检测是不是 有事件到达,或者对到达的事件逐一进行响应。或者对于多路复用IO模型来说,一旦事件响应体很大,这麼 就会原因 后续的事件迟迟得这麼出理 ,或者会影响新的事件轮询。

5.异步IO模型

  当用户tcp连接发起有另有1个read操作后,不必说时要守候,太多马上就得到了有另有1个结果。机会结果是有另有1个error时,它就知道数据还这麼 准备好,于是它才能再次发送read操作。一旦内核中的数据准备好了,或者又再次收到了用户tcp连接的请求,这麼 它马上就将数据拷贝到了用户tcp连接,或者返回。

4.信号驱动IO模型

  或者,另一方确实同步和异步才能表现在太多有方面,或者记住其关键在于多个任务和事件指在时,有另有1个事件的指在或执行是不是 会原因 整个流程的暂时守候。一般来说,才能通太多tcp连接的措施来实现异步,或者千万记住不必说将多tcp连接和异步画上等号,异步太多宏观上的有另有1个模式,采用多tcp连接来实现异步太多五种手段,或者通太多tcp连接的措施才才能实现异步。

  在传统的网络服务设计模式中,有五种比较经典的模式:

  典型的阻塞IO模型的例子为:

  http://blog.csdn.net/hguisu/article/details/7453390

3.多路复用IO模型

1.阻塞IO模型

  五种是 多tcp连接,五种是tcp连接池。

  下面就分别来介绍一下这5种IO模型的异同。

  这太多同步和异步。举个简单的例子,或者有有另有1个任务包括有另有1个子任务A和B,对于同步来说,当A在执行的过程中,B这麼守候,直至A执行完毕,B才能执行;而对于异步太多A和B才能并发地执行,B不必说守候A执行完毕前一天再执行,曾经就不必机会A的执行原因 整个任务的暂时守候。

  非阻塞太多:当某个事件机会任务在执行过程中,它发出有另有1个请求操作,机会该请求操作时要的条件不满足,会立即返回有另有1个标志信息告知条件不满足,不必经常在那守候。

  同步和异步着重点在于多个任务的执行过程中,有另有1个任务的执行是不是 会原因 整个流程的暂时守候;

  当用户tcp连接发起有另有1个IO请求操作(本文以读请求操作为例),内核会去查看要读取的数据是不是 就绪,对于阻塞IO来说,机会数据这麼 就绪,则会经常在那守候,直到数据就绪;对于非阻塞IO来说,机会数据这麼 就绪,则会返回有另有1个标志信息告知用户tcp连接当时要读的数据这麼 就绪。当数据就绪前一天,便将数据拷贝到用户tcp连接,曾经才完成了有另有1个完整性的IO读请求操作,也太多说有另有1个完整性的IO读请求操作包括有另有1个阶段:

  而阻塞和非阻塞着重点在于发出有另有1个请求操作时,机会进行操作的条件不满足是不是 会返会有另有1个标志信息告知条件不满足。

  事实上,同步和异步是有另有1个非常广的概念,它们的重点在于多个任务和事件指在时,有另有1个事件的指在或执行是不是 会原因 整个流程的暂时守候。我确实才能将同步和异步与Java中的synchronized关键字联系起来进行借喻。当多个tcp连接同時 访问有另有1个变量时,每个tcp连接访问该变量太多有另有1个事件,对于同步来说,太多哪几条tcp连接时要逐个地来访问该变量,有另有1个tcp连接在访问该变量的过程中,一点tcp连接时要守候;而对于异步来说,太多多个tcp连接不必说逐个地访问该变量,才能同時 进行访问。

  《Unix网络编程》

  阻塞太多:当某个事件机会任务在执行过程中,它发出有另有1个请求操作,或者机会该请求操作时要的条件不满足,这麼 就会经常在那守候,直至条件满足;

  http://www.cnblogs.com/dawen/archive/2011/05/18/20200358.html

  在Proactor模式中,当检测到有事件指在时,会新起有另有1个异步操作,或者交由内核tcp连接去出理 ,当内核tcp连接完成IO操作前一天,发送有另有1个通知告知操作已完成,才能得知,异步IO模型采用的太多Proactor模式。

  在《Unix网络编程》一书中提到了五种IO模型,分别是:阻塞IO、非阻塞IO、多路复用IO、信号驱动IO以及异步IO。

  1)查看数据是不是 就绪;

  接着看下面这段代码:

  事实上,同步IO和异步IO模型是针对用户tcp连接和内核的交互来说的:

  2)进行数据拷贝(内核将数据拷贝到用户tcp连接)。

  或者让你读取有另有1个文件中的内容,机会此时文件中这麼 内容可读,对于同步来说太多会经常在那守候,直至文件富含内容可读;而对于非阻塞来说,就会直接返回有另有1个标志信息告知文件中暂时无内容可读。

  这是同步IO和异步IO关键区别所在,同步IO和异步IO的关键区别反映在数据拷贝阶段是由用户tcp连接完成还是内核完成。太多有说异步IO时要要有操作系统的底层支持。

  注意同步IO和异步IO与阻塞IO和非阻塞IO是不同的两组概念。

  或者便出現了下面的五种高性能IO设计模式:Reactor和Proactor。

  对于同步IO:当用户发出IO请求操作前一天,机会数据这麼 就绪,时要通过用户tcp连接机会内核不断地去轮询数据是不是 就绪,当数据就绪时,再将数据从内核拷贝到用户tcp连接;

  太多有事实上,在非阻塞IO模型中,用户tcp连接时要不断地询问内核数据是不是 就绪,也太多非阻塞IO不必交出CPU,而会经常占用CPU。

  你说歌词 有我们都会说,让你采用 多tcp连接+ 阻塞IO 达到类似于 的效果,或者机会在多tcp连接 + 阻塞IO 中,每个socket对应有另有1个tcp连接,曾经会 造成很大的资源占用,或者尤其是对于长连接来说,tcp连接的资源经常不必释放,机会底下陆续有太多有连接一句话,就会造成性能上的瓶颈。

  对于多tcp连接模式,也太多来了client,服务器就会新建有另有1个tcp连接来出理 该client的读写事件,如下图所示:

  http://www.cnblogs.com/Anker/p/3254269.html

2.非阻塞IO模型

  从字面的意思才能看出:同步IO即 机会有另有1个tcp连接请求进行IO操作,在IO操作完成前一天,该tcp连接会被阻塞;

  也太多在异步IO模型中,IO操作的有另有1个阶段是不是 会阻塞用户tcp连接,这有另有1个阶段是不是 由内核自动完成,或者发送有另有1个信号告知用户tcp连接操作已完成。用户tcp连接中不时要再次调用IO函数进行具体的读写。这点是和信号驱动模型有所不同的,在信号驱动模型中,当用户tcp连接接收到信号表示数据机会就绪,或者时要用户tcp连接调用IO函数进行实际的读写操作;而在异步IO模型中,收到信号表示IO操作机会完成,不时要再在用户tcp连接中调用iO函数进行实际的读写操作。

  在网上有一点我们都将同步和异步分别与阻塞和非阻塞画上等号,事实上,它们是两组完整性不同的概念。注意,理解这两组概念的区别对于底下IO模型的理解非常重要。

  http://blog.csdn.net/goldensuny/article/details/200717107

  或者,为了出理 你这些有另有1个tcp连接对应有另有1个客户端模式带来的问题,提出了采用tcp连接池的措施,也太多创建有另有1个固定大小的tcp连接池,来有另有1个客户端,就从tcp连接池取有另有1个空闲tcp连接来出理 ,当客户端出理 完读写操作前一天,就交出对tcp连接的占用。或者曾经就出理 为每有另有1个客户端是不是 创建tcp连接带来的资源浪费,使得tcp连接才能重用。

  http://xmuzyq.iteye.com/blog/783218

  理解阻塞和非阻塞才能同tcp连接阻塞借喻地理解,当有另有1个tcp连接进行有另有1个请求操作时,机会条件不满足,则会被阻塞,即在那守候条件满足。

  典型的非阻塞IO模型一般如下:

  注意,异步IO是时要操作系统的底层支持,在Java 7中,提供了Asynchronous IO。

  这麼 阻塞(blocking IO)和非阻塞(non-blocking IO)的区别就在于第有另有1个阶段,机会数据这麼 就绪,在查看数据是不是 就绪的过程中是经常守候,还是直接返回有另有1个标志信息。

  在了解阻塞IO和非阻塞IO前一天,先看下有另有1个具体的IO操作过程是为什么么么会进行的。

  多路复用IO模型是目前使用得比较多的模型。Java NIO实际上太多多路复用IO。

  而异步IO为 机会有另有1个tcp连接请求进行IO操作,IO操作不必原因 请求tcp连接被阻塞。

  Java中传统的IO是不是 阻塞IO,比如通过socket来读数据,调用read()措施前一天,机会数据这麼 就绪,当前tcp连接就会经常阻塞在read措施调用那里,直到有数据才返回;而机会是非阻塞IO一句话,当数据这麼 就绪,read()措施应该返回有另有1个标志信息,告知当前tcp连接数据这麼 就绪,而是不是 经常在那里守候。

或者对于非阻塞IO是不是 有另有1个非常严重的问题,在while循环中时要不断地去询问内核数据是不是 就绪,曾经会 原因 CPU占用率非常高,或者一般具体情况下很少使用while循环你这些措施来读取数据

  另外多路复用IO为什么么么会会比非阻塞IO模型的带宽高是机会在非阻塞IO中,不断地询问socket具体情况时通过用户tcp连接去进行的,而在多路复用IO中,轮询每个socket具体情况是内核在进行的,你这些带宽要比用户tcp连接要高的多。

  在Reactor模式中,会先对每个client注册感兴趣的事件,或者有有另有1个tcp连接专门去轮询每个client是不是 有事件指在,当有事件指在时,便顺序出理 每个事件,当所有事件出理 完前一天,便再转去继续轮询,如下图所示:

这段代码太多典型的同步,在措施function中,fun1在执行的过程中会原因 后续的fun2无法执行,fun2时要守候fun1执行完毕才才能执行。

  在多路复用IO模型中,会有有另有1个tcp连接不断去轮询多个socket的具体情况,这麼当socket真正有读写事件时,才真正调用实际的IO读写操作。机会在多路复用IO模型中,只时要使用有另有1个tcp连接就才能管理多个socket,系统不时要建立新的tcp连接机会tcp连接,太多必维护哪几条tcp连接和tcp连接,或者这麼在真正有socket读写事件进行时,才会使用IO资源,太多有它大大减少了资源占用。

你这些模式确实出理 起来简单方便,或者机会服务器为每个client的连接都采用有另有1个tcp连接去出理 ,使得资源占用非常大。或者,当连接数量达到上限时,再有用户请求连接,直接会原因 资源瓶颈,严重的机会会直接原因 服务器崩溃。

  而多路复用IO模式,通过有另有1个tcp连接就才能管理多个socket,这麼当socket真正有读写事件指在才会占用资源来进行实际的读写操作。或者,多路复用IO比较适合连接数比较多的具体情况。

  阻塞IO和非阻塞IO是反映在当用户请求IO操作时,机会数据这麼 就绪,是用户tcp连接经常守候数据就绪,还是会收到有另有1个标志信息你这些点底下的。也太多说,阻塞IO和非阻塞IO是反映在IO操作的第有另有1个阶段,在查看数据是不是 就绪时是怎样出理 的。

  在前面介绍了同步和异步的区别,你这些节来看一下阻塞和非阻塞的区别。

  在信号驱动IO模型中,当用户tcp连接发起有另有1个IO请求操作,会给对应的socket注册有另有1个信号函数,或者用户tcp连接会继续执行,当内核数据就绪完会 发送有另有1个信号给用户tcp连接,用户tcp连接接收到信号前一天,便在信号函数中调用IO读写操作来进行实际的IO请求操作。

  http://alicsd.iteye.com/blog/868702

  http://www.cnblogs.com/ccdev/p/3542669.html

   机会数据这麼 就绪,就会经常阻塞在read措施。

  而异步IO:这麼IO请求操作的发出是由用户tcp连接来进行的,IO操作的有另有1个阶段是不是 由内核自动完成,或者发送通知告知用户tcp连接IO操作机会完成。也太多说在异步IO中,不必对用户tcp连接产生任何阻塞。

  最传统的五种IO模型,即在读写数据过程中会指在阻塞问题。

从这才都都上能看出,底下的五种IO模型中的多路复用IO太多采用Reactor模式。注意,底下的图中展示的 是顺序出理 每个事件,当然为了提高事件出理 带宽,才能通太多tcp连接机会tcp连接池的措施来出理 事件。

  http://www.smithfox.com/?e=191

  http://my.oschina.net/XYleung/blog/295122

  在Java NIO中,是通过selector.select()去查询每个通道是不是 有到达事件,机会这麼 事件,则经常阻塞在那里,或者你这些措施会原因 用户tcp连接的阻塞。

  或者tcp连接池是不是 它的弊端,机会连接大多是长连接,或者机会会原因 在一段时间内,tcp连接池中的tcp连接都被占用,这麼 当再有用户请求连接时,机会这麼 可用的空闲tcp连接来出理 ,就会原因 客户端连接失败,从而影响用户体验。或者,tcp连接池比较适合少量的短连接应用。

  A synchronous I/O operation causes the requesting process to be blocked until that I/O operation completes.

  An asynchronous I/O operation does not cause the requesting process to be blocked.

  举个简单的例子: