标签:
AIO:异步非阻塞
NIO:同步非阻塞
BIO:同步阻塞
(1)同步 指的是用户进程触发IO操作并等待或者轮询的去查看IO操作是否就绪
(2)异步 指用户进程触发IO操作以后便开始做自己的事情,而当IO操作已经完成的时候会得到IO完成的通知
(3)阻塞 指当试图对该文件描述符进行读写时, 如果当时没有东西可读,或者暂时不可写, 程序就进入等待状态, 直到有东西可读或者可写为止
(4)非阻塞 指如果没有东西可读, 或者不可写, 读写函数马上返回, 而不会等待
BIO、NIO、AIO适用场景分析:
BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。
NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。
AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持
Reactor模式和Proactor模式
首先来看看Reactor模式,Reactor模式应用于同步I/O的场景。我们分别以读操作和写操作为例来看看Reactor中的具体步骤:
读取操作:
1. 应用程序注册读就绪事件和相关联的事件处理器
2. 事件分离器等待事件的发生
3. 当发生读就绪事件的时候,事件分离器调用第一步注册的事件处理器
4. 事件处理器首先执行实际的读取操作,然后根据读取到的内容进行进一步的处理
写入操作类似于读取操作,只不过第一步注册的是写就绪事件。
Reactor模型:
当前NIO使用的模型,TCP建立链接后,需要使用TCP/IP的select()函数进行一个或多个链接状态的判断(通过select轮询每一个链接的状态)
Reactor中,有一个线程一直不停的轮询着链接状态,并对链接状态进行处理,是有一个线程来做这件事(这也就是轮询,导致资源的一定浪费)
TCP链接状态有四种:
(1)等待链接(accept)
(2)可读()
(3)可写()
这里进行链接轮询的时候,Reactor模型就会同步等待select()函数轮询链接状态,但,如果没有数据,立即返回
Proactor模式中读取操作和写入操作的过程
读取操作:
1. 应用程序初始化一个异步读取操作,然后注册相应的事件处理器,此时事件处理器不关注读取就绪事件,而是关注读取完成事件,这是区别于Reactor的关键。
2. 事件分离器等待读取操作完成事件
3. 在事件分离器等待读取操作完成的时候,操作系统调用内核线程完成读取操作(异步IO都是操作系统负责将数据读写到应用传递进来的缓冲区供应用程序操作,操作系统扮演了重要角色),并将读取的内容放入用户传递过来的缓存区中。这也是区别于Reactor的一点,Proactor中,应用程序需要传递缓存区。
4. 事件分离器捕获到读取完成事件后,激活应用程序注册的事件处理器,事件处理器直接从缓存区读取数据,而不需要进行实际的读取操作。
总结:
Reactor和Proactor模式的主要区别就是真正的读取和写入操作是有谁来完成的,Reactor中需要应用程序自己读取或者写入数据,而Proactor模式中,应用程序不需要进行实际的读写过程,它只需要从缓存区读取或者写入即可,操作系统会读取缓存区或者写入缓存区到真正的IO设备.
同步和异步是相对于应用和内核的交互方式而言的,同步 需要主动去询问,而异步的时候内核在IO事件发生的时候通知应用程序,而阻塞和非阻塞仅仅是系统在调用系统调用的时候函数的实现方式而已。
可以参考其它文档:http://ifeve.com/netty-reactor-4/
标签:
原文地址:http://www.cnblogs.com/rainy-shurun/p/5694719.html