IO的基本常识

1.同步

用户进程触发IO操作并等待或者轮询的去查看IO操作是否完成

2.异步

用户触发IO操作以后,可以干别的事,IO操作完成以后再通知当前线程继续处理

3.阻塞

当一个线程调用 read() 或 write()时,该线程被阻塞,直到有一些数据被读取或写入,该线程在此期间不能执行其他任务

4.非阻塞

当线程从某通道进行读写数据时,若没有数据可用时,该线程可以进行其他任务。线程通常将非阻塞 IO 的空闲时间用于在其他通道上执行 IO 操作,所以单独的线程可以管理多个输入和输出通道。

IO事件驱动模式

在IO读写时,把 IO请求 与 读写操作 分离调配进行,需要用到事件分离器。根据处理机制的不同,事件分离器又分为:同步的Reactor和异步的Proactor。

Reactor模型:

 - 应用程序在事件分离器注册 读就绪事件 和 读就绪事件处理器
- 事件分离器等待读就绪事件发生
- 读就绪事件发生,激活事件分离器,分离器调用 读就绪事件处理器(即:可以进行读操作了,开始读)
- 读事件处理器开始进行读操作,把读到的数据提供给程序使用

Proactor模型:

 - 应用程序在事件分离器注册 读完成事件 和 读完成事件处理器,并向操作系统发出异步读请求
- 事件分离器等待操作系统完成读取
- 在分离器等待过程中,操作系统利用并行的内核线程执行实际的读操作,并将结果数据存入用户自定义缓冲区,最后通知事件分离器读操作完成
- 事件分离器监听到 读完成事件 后,激活 读完成事件的处理器
- 读完成事件处理器 处理用户自定义缓冲区中的数据给应用程序使用

同步和异步的区别就在于 读 操作由谁完成:同步的Reactor是指程序发出读请求后,由分离器监听到可以进行读操作时通知事件处理器进行读操作,异步的Proactor是指程序发出读请求后,操作系统立刻异步地进行读操作了,读完之后在通知分离器,分离器激活处理器直接取用已读到的数据。

同步阻塞IO(BIO)

我们熟知的Socket就是BIO,每一个socket套接字需要使用一个线程来处理。建立连接、进行读写操作的时候都可能阻塞。在服务器端如果要支持并发的连接时,需要更多的线程。连接不做任何事情的时候会造成不必要的线程开销,可通过线程池来改善。

同步非阻塞IO(NIO)

New IO是对BIO的改进,基于Reactor模型。我们知道,一个socket连接只有在特定时间才会发生数据传输IO操作,大部分时间这个“数据通道”是空闲的,但还是占用着线程。NIO作出的改进就是“多个连接一个线程”,在连接到服务端的众多socket中,只有需要进行IO操作的才能获取服务端的处理线程进行IO。这样就不会因为线程不够用而限制了socket的接入。客户端的socket连接到服务端时,就会在事件分离器注册一个 IO请求事件 和 IO 事件处理器。在该连接发生IO请求时,IO事件处理器就会启动一个线程来处理这个IO请求,不断尝试获取系统的IO的使用权限,则通知这个socket进行IO数据传输。

NIO主要有三大核心部分:Channel(通道),Buffer(缓冲区), Selector。传统IO基于字节流和字符流进行操作,而NIO基于Channel和Buffer(缓冲区)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。Selector(选择区)用于监听多个通道的事件(比如:连接打开,数据到达)。因此,单个线程可以监听多个数据通道。

NIO基于Channel和Buffer(缓冲区)进行操作

Selector(选择区)用于监听多个通道的事件

异步阻塞IO(AIO)

NIO是同步的IO,是因为程序需要IO操作时,必须获得了IO权限后亲自进行IO操作才能进行下一步操作。AIO是对NIO的改进(所以AIO又叫NIO.2),它是基于Proactor模型的。每个socket连接在事件分离器注册 IO完成事件 和 IO完成事件处理器。程序需要进行IO时,向分离器发出IO请求并把所用的Buffer区域告知分离器,分离器通知操作系统进行IO操作,操作系统自己不断尝试获取IO权限并进行IO操作(数据保存在Buffer区),操作完成后通知分离器;分离器检测到 IO完成事件,则激活 IO完成事件处理器,处理器会通知程序说“IO已完成”,程序知道后就直接从Buffer区进行数据的读写。

AIO是发出IO请求后,由操作系统自己去获取IO权限并进行IO操作;NIO则是发出IO请求后,由线程不断尝试获取IO权限,获取到后通知应用程序自己进行IO操作。

总结

BIO,NIO,AIO可以简述如下:

BIO是同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。

NIO是同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。

AIO是异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。

BIO、NIO、AIO适用场景分析:

BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高

NIO方式适用于连接数目多且连接比较短的架构,可充分利用服务器资源

AIO方式使用于连接数目多且连接比较长的架构,充分调用OS参与并发操作

深入分析JAVA IO(BIO、NIO、AIO)的更多相关文章

  1. Java提供了哪些IO方式?IO, BIO, NIO, AIO是什么?

    IO一直是软件开发中的核心部分之一,而随着互联网技术的提高,IO的重要性也越来越重.纵观开发界,能够巧妙运用IO,不但对于公司,而且对于开发人员都非常的重要.Java的IO机制也是一直在不断的完善,以 ...

  2. JAVA 中BIO,NIO,AIO的理解

    [转自]http://qindongliang.iteye.com/blog/2018539 ?????????????????????在高性能的IO体系设计中,有几个名词概念常常会使我们感到迷惑不解 ...

  3. JAVA 中BIO,NIO,AIO的理解以及 同步 异步 阻塞 非阻塞

    在高性能的IO体系设计中,有几个名词概念常常会使我们感到迷惑不解.具体如下: 序号 问题 1 什么是同步? 2 什么是异步? 3 什么是阻塞? 4 什么是非阻塞? 5 什么是同步阻塞? 6 什么是同步 ...

  4. JAVA 中BIO,NIO,AIO的理解 (转)

    转自: http://qindongliang.iteye.com/blog/2018539 另外类似可参考资料 :http://www.360doc.com/content/13/1029/20/9 ...

  5. Java中BIO,NIO,AIO的理解

    在高性能的IO体系设计中,有几个名词概念常常会使我们感到迷惑不解.具体如下: 1 什么是同步? 2 什么是异步? 3 什么是阻塞? 4 什么是非阻塞? 5 什么是同步阻塞? 6 什么是同步非阻塞? 7 ...

  6. (转)也谈BIO | NIO | AIO (Java版)

    原文地址: https://my.oschina.net/bluesky0leon/blog/132361 关于BIO | NIO | AIO的讨论一直存在,有时候也很容易让人混淆,就我的理解,给出一 ...

  7. 也谈BIO | NIO | AIO (Java版--转)

    关于BIO | NIO | AIO的讨论一直存在,有时候也很容易让人混淆,就我的理解,给出一个解释: BIO | NIO | AIO,本身的描述都是在Java语言的基础上的.而描述IO,我们需要从两个 ...

  8. IO回忆录之怎样过目不忘(BIO/NIO/AIO/Netty)

    有热心的网友加我微信,时不时问我一些技术的或者学习技术的问题.有时候我回微信的时候都是半夜了.但是我很乐意解答他们的问题.因为这些年轻人都是很有上进心的,所以在我心里他们就是很优秀的,我愿意多和努力的 ...

  9. I/O模型系列之三:IO通信模型BIO NIO AIO

    一.传统的BIO 网络编程的基本模型是Client/Server模型,也就是两个进程之间进行相互通信,其中服务端提供位置信息(绑定的IP地址和监听端口),客户端通过连接操作向服务端监听的地址发起连接请 ...

  10. java BIO/NIO/AIO 学习

    一.了解Unix网络编程5种I/O模型 1.1.阻塞式I/O模型 阻塞I/O(blocking I/O)模型,进程调用recvfrom,其系统调用直到数据报到达且被拷贝到应用进程的缓冲区中或者发生错误 ...

随机推荐

  1. sql过程的条件是IN,用脚本执行

    DECLARE @sql nvarchar(); DECLARE @inStr nvarchar(); SET @inStr='''条件1'',''条件2'''; set @sql='SELECT * ...

  2. php 环境搭建问题

    项目过程中需要用到 PHP环境 https://www.cnblogs.com/cyrfr/p/6483529.html APACHE无法启动:THE REQUEST OPERATION HAS FA ...

  3. 排序算法原理及代码实现(c#)

    1.插入排序 把第一个元素看做已排序数组放在有序数组中,从第二个元素开始,依次把无序数组元素取出和有序数组中的元素逐个比较,并放在有序数组的正确位置上. /// <summary> /// ...

  4. IP-reputation feature

    IP-reputation feature https://blog.norz.at/citrix-netscaler-ip-reputation-feature/ I recently had to ...

  5. 【Salesforce】入门篇

    Salesforce.com 一开始是一个云端的销售自动化(Sales Force Automation, SFA)以及客户关系管理工具(Customer Relationship Managemen ...

  6. 二叉树BinaryTree构建测试(无序)

    此测试仅用于二叉树基本的性质测试,不包含插入.删除测试(此类一般属于有序树基本操作). //二叉树树类 public class BinaryTree { public TreeNode root; ...

  7. C和指针--高级声明

    1. int *f(); 分析:必须确定表达式*f()是如何进行求值的.首先执行的是函数调用操作符(),因为它的优先级高于间接访问操作符.因此,f是一个函数,它的返回值类型是一个指向整型的指针. 2. ...

  8. 搭建nginx文件服务器

    一.安装nginx服务 apt install nginx 二.修改nginx配置文件 cd /etc/nginx/conf.d/ vim download_server.conf server { ...

  9. 页面Header自适应屏幕

    <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8& ...

  10. Java字节码方法表结构深度剖析

    继续上一次[https://www.cnblogs.com/webor2006/p/9459681.html]的字节码分析,这次来分析一下最为复杂的方法表的信息,如下: 而上一次分析到了属性表的位置在 ...