NIO与AIO,同步/异步,阻塞/非阻塞

摘要:
因此,clear()用于准备缓冲区的数据输入和put()。在将通道中的数据读取到缓冲区之前,首先将当前位置和限制之间的数据复制到缓冲区的开头。下次读取的新数据将附加到以下5}SelectionKey。是否阻止从内核缓冲区复制到应用程序缓冲区的数据。

1.flip(),compact(),与clear()的使用

flip()内部实现,先将limit设为当前位置,再将缓冲区的postion设为0,所以是为将缓冲区的数据写出到其它通道或者get()作准备。

clear()内部实现,将limit设为缓冲区的容量,position设为0,limit的不同为clear()与flip()的区别,所以clear()是为缓冲区的数据读入与put()作准备。当将通道中的数据读入缓冲区前,应该用clear(),不能用flip()

compact()内部实现,首先将当前位置与limit之间的数据复制到缓冲区的开始处,假设复制了n字节的数据,然后将position设为n+1,limit设为容量,所以是为了继续往缓冲区读入数据或者put()作准备,即为追加数据作准备。

flip()与compact()配合使用的例子:

1 while(channel.read(buffer)>=0 || buffer.position!=0){
2     buffer.flip();    //为写出数据作准备,将position移至0
3     channel2.write(buffer);
4     buffer.compact();    //假如上一步只写出了部分数据,此方法则可以防止数据丢失,下次读入的新数据将追加在后边
5 }

SelectionKey关于accept,connect,read,write有几个常量,这几个值都是2的整数次幂,如1,4,8,16,因此进行 | 和 ^ 运算就如同十进制中的加法和减法,这样可以灵活的注册和注销关注的事件.

如注销监听读事件,key.interestOps(key.interestOps()^SelectionKey.OP_READ)  (1|4|8)^4=9  ^优先级比|高,因此括号不能少

2.关于同步,异步,阻塞,非阻塞的区别

各种I/O模型的准确介绍:

http://blog.csdn.net/shallwake/article/details/5265287?reload

AIO介绍:还有一个相关服务器框架yanf4j :

http://www.iteye.com/topic/472333 

同步与异步的区分标准:数据从内核缓冲区(kernel buffer)复制到应用程序缓冲区(application buffer)这个阶段是否阻塞。

所以从这个角度看,阻塞I/O,非阻塞I/O,多路复用I/O,signal driven I/O(仅限于Unix)这四种I/O模型都是同步I/O.

而asynchronous I/O操作系统在copy数据到应用缓冲区完成以后才通知应用程序,所以是纯异步的。

在1.4的NIO中,阻塞的是select,I/O并不阻塞,用一个Reactor线程可以监听多个通道的事件,并分发给其它的处理线程。这个select可以看作一个代理,它会去轮询所有注册的通道事件,看事件是否已发生,所以本质上NIO可看成是同步非阻塞I/O.

NIO应用的是Reactor模式,selector是reactor,而channel可看作是事件处理程序,如读就绪事件发生时,如果通道设置的是非阻塞模式,则处理程序会将数据从内核缓冲区复制到通道中(应用缓冲区),紧接着我们在程序中从通道中读取数据时就不会阻塞了。

而NIO的同步体现在第一阶段仍然需要通过轮询来获知读/写/是否已就绪,然后事件分离器调用相应事件处理程序。

AIO的Proactor模式,不关心读就绪事件,只关心读/写完成事件,完成以后直接回调之前注册的处理程序。I/O读写,缓冲区数据的移动全部由内核完成。

在1.7的AIO中,本身也不会阻塞,对accept,read,write的调用都会立即返回,内核完成I/O操作以后,会将后续处理任务提交给线程池来执行,即回调,这个Proactor就是当初注入的AsynchronousChannelGroup,它持有这个线程池。

免责声明:文章转载自《NIO与AIO,同步/异步,阻塞/非阻塞》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Spring整合JUnit4测试使用注解引入多个配置文件Qt 学习之路:视图选择 (QItemSelectionModel)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

网页分页数据的三种抓取方式

     相信所有个人网站的站长都有抓取别人数据的经历吧,目前抓取别人网站数据的方式无非两种方式:      一、使用第三方工具,其中最著名的是火车头采集器,在此不做介绍。      二、自己写程序抓取,这种方式要求站长自己写程序,可能对对站长的开发能力有所要求了。      本人起初也曾试着用第三方的工具抓取我所需要的数据,由于网上的流行的第三方工具不...

id 自增------删除数据后恢复到删除前自增id

删除数据后,执行下面语句:      ALTER TBALE TableName AUTO_INCREMENT=1 mysql删除比较 一、DROP   drop  table tablename     绝招:删除内容和定义,释放空间。简单来说就是把整个表去掉.以后要新增数据是不可能的,除非新增一个表 二、TRUNCATE   truncate tabl...

将xls/csv数据导入到ES中

一.导入MySQL数据库中 (1)通过Navicat导入向导直接导入即可 (2)代码方式导入 【如果字段太多,这种方式做肯定不现实】 csv导入mysql数据库 -- 按需修改即可 package com.blb.mysql_java_es.util; import org.springframework.context.annotation.Bean...

An error occurred while attempting to initialize the Borland Database Engine (error $2108)

转载:http://hi.baidu.com/hbxjzlq/blog/item/592c6bae9e39fefdfbed5008.html BDE初始化失败 解决方法:重新安装BDE BDE简介. 要开发数据库应用程序首先要解决数据源的问题,那么什么是数据源呢?简单来讲数据源就是实实在在的数据,通常是各种数据表。 有了数据源我们就有了开发程序的依据,然而...

网络通信IO的演变过程(一)(一个门外汉的理解)

以前从来不懂IO的底层,只知道一个大概,就是输入输出的管道怼到一起,然后就可以传输数据了。 最近看了周志垒老师的公开课后,醍醐灌顶。 所以做一个简单的记录。 0 计算机组成原理相关 0.1. 计算机的基本组成大家都了解一点,如下图,当操作系统启动的时候,首先进入内存的除了BIOS,然后就是Linux内核程序。 内核暂时先理解成系统程序,比如我们想通过键...

Sword HTTP协议之chunk介绍

简介 当HTTP服务器无法预知报文长度时,可以使用Transfer-Encoding:chunk模式来传输数据即HTTP服务器一边产生数据,一边发给客户端,HTTP服务器报文头需要设置"Transfer-Encoding: chunked"来代替Content-Length。 编码格式 如果一个HTTP消息(请求消息或应答消息)的Transfer-Enco...