Java NIO:浅析I/O模型

  • 时间:
  • 浏览:0

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

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

  有四种 是 多tcp连接,有四种 是tcp连接池。

  而阻塞和非阻塞着重点在于发出原先请求操作时,不可能 进行操作的条件不满足否有会返会原先标志信息告知条件不满足。

  事实上,同步和异步是原先非常广的概念,它们的重点在于多个任务和事件指在时,原先事件的指在或执行否有会原因整个流程的暂时等候。我虽然都不还能不能 将同步和异步与Java中的synchronized关键字联系起来进行移就。当多个tcp连接共同访问原先变量时,每个tcp连接访问该变量如果我原先事件,对于同步来说,如果我那先 tcp连接不还能不能 逐个地来访问该变量,原先tcp连接在访问该变量的过程中,有些tcp连接不还能不能 等候;而对于异步来说,如果我多个tcp连接并不逐个地访问该变量,都不还能不能 共同进行访问。

3.多路复用IO模型

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

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

  阻塞IO和非阻塞IO是反映在当用户请求IO操作时,不可能 数据如此就绪,是用户tcp连接老会 等候数据就绪,还是会收到原先标志信息有些点上方的。也如果我说,阻塞IO和非阻塞IO是反映在IO操作的第原先阶段,在查看数据否有就绪时是如保除理的。

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

5.异步IO模型

  异步IO模型才是最理想的IO模型,在异步IO模型中,当用户tcp连接发起read操作如果,立刻就都不还能不能 结束去做其它的事。而被委托人面,从内核的深层,当它受到原先asynchronous read如果,它会立刻返回,说明read请求不可能 成功发起了,如保让不必对用户tcp连接产生任何block。如保让,内核会等候数据准备完成,如保让将数据拷贝到用户tcp连接,当有些切都完成如果,内核会给用户tcp连接发送原先信号,告诉它read操作完成了。也如果我用户tcp连接删改不必还能不能 实际的整个IO操作是如保进行的,只不还能不能 先发起原先请求,当接收内核返回的成功信号时表示IO操作不可能 完成,都不还能不能 直接去使用数据了。

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

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

  在网上有有些亲戚亲戚人们都都将同步和异步分别与阻塞和非阻塞画上等号,事实上,它们是两组删改不同的概念。注意,理解这两组概念的区别对于上方IO模型的理解非常重要。

  在Proactor模式中,当检测到有事件指在时,会新起原先异步操作,如保让交由内核tcp连接去除理,当内核tcp连接完成IO操作如果,发送原先通知告知操作已完成,都不还能不能 得知,异步IO模型采用的如果我Proactor模式。

  如保让便老会 出現了下面的有四种 高性能IO设计模式:Reactor和Proactor。

  对于同步IO:当用户发出IO请求操作如果,不可能 数据如此就绪,不还能不能 通过用户tcp连接不可能 内核不断地去轮询数据否有就绪,当数据就绪时,再将数据从内核拷贝到用户tcp连接;

  也如果我在异步IO模型中,IO操作的原先阶段全是会阻塞用户tcp连接,这原先阶段全是由内核自动完成,如保让发送原先信号告知用户tcp连接操作已完成。用户tcp连接中不必还能不能 再次调用IO函数进行具体的读写。这点是和信号驱动模型有所不同的,在信号驱动模型中,当用户tcp连接接收到信号表示数据不可能 就绪,如保让不还能不能 用户tcp连接调用IO函数进行实际的读写操作;而在异步IO模型中,收到信号表示IO操作不可能 完成,不必还能不能 再在用户tcp连接中调用iO函数进行实际的读写操作。

  1)查看数据否有就绪;

  在Java NIO中,是通过selector.select()去查询每个通道否有有到达事件,不可能 如此事件,则老会 阻塞在那里,如保让有些法律依据 会原因用户tcp连接的阻塞。

  在了解阻塞IO和非阻塞IO如果,先看下原先具体的IO操作过程是为什么会么会进行的。

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

  这如果我同步和异步。举个简单的例子,假使 有原先任务包括原先子任务A和B,对于同步来说,当A在执行的过程中,B还能不能不能了等候,直至A执行完毕,B不还能不能执行;而对于异步如果我A和B都不还能不能 并发地执行,B并不等候A执行完毕如果再执行,原先就不必不可能 A的执行原因整个任务的暂时等候。

  同步和异步着重点在于多个任务的执行过程中,原先任务的执行否有会原因整个流程的暂时等候;

  在信号驱动IO模型中,当用户tcp连接发起原先IO请求操作,会给对应的socket注册原先信号函数,如保让用户tcp连接会继续执行,当内核数据就绪后要 发送原先信号给用户tcp连接,用户tcp连接接收到信号如果,便在信号函数中调用IO读写操作来进行实际的IO请求操作。

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

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

如保让对于非阻塞IO全是原先非常严重的问提,在while循环中不还能不能 不断地去询问内核数据否有就绪,原先会原因CPU占用率非常高,如保让一般具体情况下很少使用while循环有些法律依据 来读取数据

  当用户tcp连接发出IO请求如果,内核会去查看数据否有就绪,不可能 如此就绪就会等候数据就绪,而用户tcp连接就会指在阻塞具体情况,用户tcp连接交出CPU。当数据就绪如果,内核会将数据拷贝到用户tcp连接,并返回结果给用户tcp连接,用户tcp连接才解除block具体情况。

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

  Java中传统的IO全是阻塞IO,比如通过socket来读数据,调用read()法律依据 如果,不可能 数据如此就绪,当前tcp连接就会老会 阻塞在read法律依据 调用那里,直到有数据才返回;而不可能 是非阻塞IO话语,当数据如此就绪,read()法律依据 应该返回原先标志信息,告知当前tcp连接数据如此就绪,而全是老会 在那里等候。

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

  从字面的意思都不还能不能 看出:同步IO即 不可能 原先tcp连接请求进行IO操作,在IO操作完成如果,该tcp连接会被阻塞;

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

  对于多tcp连接模式,也如果我来了client,服务器就会新建原先tcp连接来除理该client的读写事件,如下图所示:

从这里都不还能不能 看出,上方的有四种 IO模型中的多路复用IO如果我采用Reactor模式。注意,上方的图中展示的 是顺序除理每个事件,当然为了提高事件除理下行速率 ,都不还能不能 通不要 tcp连接不可能 tcp连接池的法律依据 来除理事件。

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

这段代码如果我典型的同步,在法律依据 function中,fun1在执行的过程中会原因后续的fun2无法执行,fun2不还能不能 等候fun1执行完毕才都不还能不能 执行。

4.信号驱动IO模型

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

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

  前面有四种 IO模型实际上都属于同步IO,还能不能不能了最后有四种 是真正的异步IO,不可能 无论是多路复用IO还是信号驱动模型,IO操作的第原先阶段后要 引起用户tcp连接阻塞,也如果我内核进行数据拷贝的过程后要 让用户tcp连接阻塞。

  当用户tcp连接发起原先IO请求操作(本文以读请求操作为例),内核会去查看要读取的数据否有就绪,对于阻塞IO来说,不可能 数据如此就绪,则会老会 在那等候,直到数据就绪;对于非阻塞IO来说,不可能 数据如此就绪,则会返回原先标志信息告知用户tcp连接当不还能不能 读的数据如此就绪。当数据就绪如果,便将数据拷贝到用户tcp连接,原先才完成了原先删改的IO读请求操作,也如果我说原先删改的IO读请求操作包括原先阶段:

  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.

参考资料:

  如保让,被委托人虽然同步和异步都不还能不能 表现在什么都有方面,如保让记住其关键在于多个任务和事件指在时,原先事件的指在或执行否有会原因整个流程的暂时等候。一般来说,都不还能不能 通不要 tcp连接的法律依据 来实现异步,如保让千万记住并不将多tcp连接和异步画上等号,异步如果我宏观上的原先模式,采用多tcp连接来实现异步如果我有四种 手段,如保让通不要 tcp连接的法律依据 也都不还能不能 实现异步。

  你说那先 有亲戚亲戚人们都都会说,我都不还能不能 采用 多tcp连接+ 阻塞IO 达到类式的效果,如保让不可能 在多tcp连接 + 阻塞IO 中,每个socket对应原先tcp连接,原先会造成很大的资源占用,如保让尤其是对于长连接来说,tcp连接的资源老会 不必释放,不可能 上方陆续有什么都有连接话语,就会造成性能上的瓶颈。

  假使 我都不还能不能 读取原先文件中的内容,不可能 此时文件中如此内容可读,对于同步来说如果我会老会 在那等候,直至文件涵盖内容可读;而对于非阻塞来说,就会直接返回原先标志信息告知文件中暂时无内容可读。

  这如果我阻塞和非阻塞的区别。也如果我说阻塞和非阻塞的区别关键在于当发出请求原先操作时,不可能 条件不满足,是会老会 等候还是返回原先标志信息。

  在多路复用IO模型中,会有原先tcp连接不断去轮询多个socket的具体情况,还能不能不能了当socket真正有读写事件时,才真正调用实际的IO读写操作。不可能 在多路复用IO模型中,只不还能不能 使用原先tcp连接就都不还能不能 管理多个socket,系统不必还能不能 建立新的tcp连接不可能 tcp连接,如果我必维护那先 tcp连接和tcp连接,如保让还能不能不能了在真正有socket读写事件进行时,才会使用IO资源,什么都有它大大减少了资源占用。

  《Unix网络编程》

  举个简单的例子:

  而多路复用IO模式,通过原先tcp连接就都不还能不能 管理多个socket,还能不能不能了当socket真正有读写事件指在才会占用资源来进行实际的读写操作。如保让,多路复用IO比较适合连接数比较多的具体情况。

  在Reactor模式中,会先对每个client注册感兴趣的事件,如保让有原先tcp连接专门去轮询每个client否有有事件指在,当有事件指在时,便顺序除理每个事件,当所有事件除理完如果,便再转去继续轮询,如下图所示:

   不可能 数据如此就绪,就会老会 阻塞在read法律依据 。

  理解阻塞和非阻塞都不还能不能 同tcp连接阻塞移就地理解,当原先tcp连接进行原先请求操作时,不可能 条件不满足,则会被阻塞,即在那等候条件满足。

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

1.阻塞IO模型

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

  非阻塞如果我:当某个事件不可能 任务在执行过程中,它发出原先请求操作,不可能 该请求操作不还能不能 的条件不满足,会立即返回原先标志信息告知条件不满足,不必老会 在那等候。

  而异步IO:还能不能不能了IO请求操作的发出是由用户tcp连接来进行的,IO操作的原先阶段全是由内核自动完成,如保让发送通知告知用户tcp连接IO操作不可能 完成。也如果我说在异步IO中,不必对用户tcp连接产生任何阻塞。

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

2.非阻塞IO模型

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

  当用户tcp连接发起原先read操作后,并不必还能不能 等候,如果我马上就得到了原先结果。不可能 结果是原先error时,它就知道数据还如此准备好,于是它都不还能不能 再次发送read操作。一旦内核中的数据准备好了,如保让又再次收到了用户tcp连接的请求,如此它马上就将数据拷贝到了用户tcp连接,如保让返回。

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

  接着看下面这段代码:

  不过要注意的是,多路复用IO模型是通过轮询的法律依据 来检测否有有事件到达,如保让对到达的事件逐一进行响应。如保让对于多路复用IO模型来说,一旦事件响应体很大,如此就会原因后续的事件迟迟得还能不能不能了除理,如保让会影响新的事件轮询。

有些模式虽然除理起来简单方便,如保让不可能 服务器为每个client的连接都采用原先tcp连接去除理,使得资源占用非常大。如保让,当连接数量达到上限时,再有用户请求连接,直接会原因资源瓶颈,严重的不可能 会直接原因服务器崩溃。

这段代码是有四种 典型的异步,fun1的执行不必影响到fun2的执行,如保让fun1和fun2的执行不必原因其后续的执行过程指在暂时的等候。

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

  什么都有事实上,在非阻塞IO模型中,用户tcp连接不还能不能 不断地询问内核数据否有就绪,也如果我非阻塞IO不必交出CPU,而会老会 占用CPU。

  阻塞如果我:当某个事件不可能 任务在执行过程中,它发出原先请求操作,如保让不可能 该请求操作不还能不能 的条件不满足,如此就会老会 在那等候,直至条件满足;

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

  而异步IO为 不可能 原先tcp连接请求进行IO操作,IO操作不必原因请求tcp连接被阻塞。

  如保让,为了除理有些原先tcp连接对应原先客户端模式带来的问提,提出了采用tcp连接池的法律依据 ,也如果我创建原先固定大小的tcp连接池,来原先客户端,就从tcp连接池取原先空闲tcp连接来除理,当客户端除理完读写操作如果,就交出对tcp连接的占用。如保让原先就除理为每原先客户端全是创建tcp连接带来的资源浪费,使得tcp连接都不还能不能 重用。

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

  如此阻塞(blocking IO)和非阻塞(non-blocking IO)的区别就在于第原先阶段,不可能 数据如此就绪,在查看数据否有就绪的过程中是老会 等候,还是直接返回原先标志信息。

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

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