要搞明白IO相关的概念,首先就得弄清楚同步与异步,阻塞与非阻塞到底是什么意思。

同步与异步

想要搞明白IO模型,就先得搞明白“同步”与“异步”的关系。

所谓的“同步”,比如说调用者去调用一个接口,这个接口比如要执行一些磁盘文件读写操作,或者是网络通信操作。

假设是“同步”的模式,调用者必须要等待这个接口的磁盘读写或者网络通信的操作执行完毕了,调用者才能返回,这就是“同步”,如下图所示:

所谓的“异步”,就是说这个调用者调用接口之后,直接就返回了,他去干别的事儿了,也不管那个接口的磁盘读写或者是网络通信是否成功。

然后这个接口后续如果干完了自己的任务,比如写完了文件或者是什么的,会反过来通知调用者,之前你的那个调用成功了。可以通过一些内部通信机制来通知,也可以通过回调函数来通知,如下图。

用生活中的例子理解同步与异步

如果给大家举个生活中的例子,那么就可以用买烟这个事儿来举个例子

比如说现在你要去一个柜台买很多条香烟,但是现在柜台没那么多货,他需要打电话给库房来查一下有没有足够的货。

这个时候,库房的工作人员正好去吃饭了,那现在你有两种选择:

第一种选择,你可以在柜台等着,一直等待库房工作人员回来,柜台专员打通电话给他查到了库存是否充足,你再走。

这个就是“同步”,你找柜台工作人员买香烟,他要打电话给库房工作人员问库存,如果你选择“同步”模式,那么你就在柜台一直等着,直到成功查询到库存为止。

第二种选择,你可以先回家干点儿别的,比如说洗衣服做饭之类的,然后过了一会儿,柜台工作人员打通电话给库房工作人员,查到香烟库存了,就会打个电话给你,告诉你这个事儿。

这就是“异步”,你跟柜台工作人员说了这个事儿,就直接走了,干别的去了,柜台工作人员后面完成他的任务之后,就会反过来打电话回调通知你。

阻塞与非阻塞

实际上阻塞与非阻塞的概念,通常是针对底层的IO操作来说的。

比如现在我们的程序想要通过网络读取数据,如果是阻塞IO模式,一旦发起请求到操作系统内核去从网络中读取数据,就会阻塞在那里,必须要等待网络中的数据到达了之后,才能从网络读取数据到内核,再从内核返回给程序,如下图。

非阻塞,指的就是程序发送请求给内核要从网络读取数据,但是此时网络中的数据还没到,此时不会阻塞住,内核会返回一个异常消息给程序。

程序就可以干点儿别的,然后过一会儿再来发起一次请求给内核,让内核尝试从网络读取数据。

因为如果网络中的数据还没到位,是不会阻塞住程序的,需要程序自己不断的轮询内核去尝试读取数据,所以这种IO就是非阻塞的。如下图:

大家不要把“同步/异步”概念和“阻塞/非阻塞”概念混淆起来,实际上他们是两组不同的概念。

“同步/异步”更多的是针对比如接口调用,服务调用,API类库调用,类似这样的场景。

而“阻塞/非阻塞”概念针对的是底层IO操作的场景,比如磁盘IO,网络IO。但是在Java IO模型里,两种概念之间是有一定的关联关系的 。

Unix支持的5种IO模型

Unix操作系统支持的IO模型主要就是5种:

  1. 阻塞IO:就是上面图里的那种阻塞IO模式,程序发起请求之后会阻塞,一直到系统内核发现网络中有数据到达了,拷贝数据给程序进程了,才能返回

  2. 非阻塞IO:就是上面图里的那种非阻塞IO模式,程序发起请求读取数据,系统内核发现网络数据还没到,就返回一个异常信息,程序不会阻塞在IO操作上,但是过一会儿还得再来发起请求给内核,直到内核发现网络数据到达了,此时就会拷贝数据给程序进程

  3. IO多路复用:这个下面来讲

  4. 信号驱动式IO:一般很少用到,这里不说明

  5. 异步IO:下面来讲

JDK 1.4之前的同步阻塞IO

在JDK 1.4之前,主要就是同步阻塞IO模型,在Java里叫做BIO。

在Java代码里调用IO相关接口,发起IO操作之后,Java程序就会同步等待,这个同步指的是Java程序调用IO API接口的层面而言。

而IO API在底层的IO操作是基于阻塞IO来的,向操作系统内核发起IO请求,系统内核会等待数据就位之后,才会执行IO操作,执行完毕了才会返回。

JDK 1.4之后的同步非阻塞NIO

在JDK 1.4之后提供了NIO,他的概念是同步非阻塞,也就是说如果你调用NIO接口去执行IO操作,其实还是同步等待的,但是在底层的IO操作上 ,会对系统内核发起非阻塞IO请求,以非阻塞的形式来执行IO。

也就是说,如果底层数据没到位,那么内核返回异常信息,不会阻塞住,但是NIO接口内部会采用非阻塞方式过一会儿再次调用内核发起IO请求,直到成功为止。

但是之所以说是同步非阻塞,这里的“同步”指的就是因为在你的Java代码调用NIO接口层面是同步的,你还是要同步等待底层IO操作真正完成了才可以返回,只不过在执行底层IO的时候采用了非阻塞的方式来执行罢了。

NIO网络通信与IO多路复用模型

实际上,如果基于NIO进行网络通信,采取的就是多路复用的IO模型,这个多路复用IO模型针对的是网络通信中的IO场景来说的。

简单来说,就是在基于Socket进行网络通信的时候,如果有多个客户端跟你的服务端建立了Socket连接,那你就需要维护多个Socket连接。

而所谓的多路复用IO模型,就是说你的Java代码直接通过一个select函数调用,直接会进入一个同步等待的状态。

这也是为什么说NIO一定是“同步”的,因为你必须在这里同步等待某个Socket连接有请求到来。

接着你就要同步等着select函数去对底层的多个 Socket 连接进行轮询,不断的查看各个 Socket 连接谁有请求到达,就可以让select函数返回,交给我们的Java程序来处理。

select函数在底层会通过非阻塞的方式轮询各个Socket,任何一个Socket如果没有数据到达,那么非阻塞的特性会立即返回一个信息。

然后select函数可以轮询下一个Socket,不会阻塞在某个Socket上,所以底层是基于这种非阻塞的模式来“监视”各个Socket谁有数据到达的。

这就是所谓的“同步非阻塞”,但是因为操作系统把上述工作都封装在一个select函数调用里了,可以对多路Socket连接同时进行监视,所以就把这种模型称之为“IO多路复用”模型

通过这种IO多路复用的模型,就可以用一个线程,调用一个select函数,然后监视大量的客户端连接了,如下图。

AIO以及异步IO模型

最后就是JDK 1.7之后,又支持了AIO,也叫做NIO 2.0,他就支持异步IO模型了。

我们先说一下异步IO模型是什么意思。

简单来说,就是你的Java程序可以基于AIO API发起一个请求,比如说接收网络数据,AIO API底层会基于异步IO模型来调用操作系统内核。

此时不需要去管这个IO是否成功了,AIO接口会直接返回,你的Java程序也会直接返回。

然后,你的Java程序就可以去干别的事儿了。大家联想一下上面说的那个异步的例子,就可以理解这里为什么叫做异步了。

因为BIO、NIO都是同步的,你发起IO请求,都必须同步等待IO操作完成。

但是这里你发起一个IO请求,直接AIO接口就返回了,你就可以干别的事儿了,纯异步的方式。

不过你需要提供一个回调函数给AIO接口,一旦底层系统内核完成了具体的IO请求,比如网络读写之类的,就会回调你提供的回调函数。

比如说你要是通过网络读取数据,那么此时AIO接口就会把操作系统异步读取到的数据交给你的回调函数。

整个过程如下图:

面试题:聊聊Unix与Java的IO模型?相关推荐

  1. Java的IO模型基于网络编程利弊分析

    JAVA的IO模型基于网络编程利弊分析 一.IO通俗理解 IO的过程 思考①答案:文件句柄 思考②答案: 阻塞/非阻塞 IO(程序对内核空间数据拷贝到用户空间阶段的耗时操作的等待方式) 同步/异步IO ...

  2. Linux网络IO模型及JAVA中IO模型

    文章目录 1.概述 2.Linux网络IO模型 2.1.阻塞IO模型 2.2.非阻塞IO模型 2.3.IO复用模型 2.3.1.select 2.3.2.poll 2.3.3.epoll 2.4.信号 ...

  3. Unix网络编程之IO模型

    首先,我们要了解IO模型先要知道在底层操作系统是通过哪些设备来实现数据的传输,其次要了解IO模型中哪些是发生阻塞调用操作,然后有了上述的基本认知之后,开始来了解IO模型是如何演进,最后通过IO模型的演 ...

  4. Java的Io模型你了解多少?北大青鸟java培训课程

    目录 由于文档内容过多,共计有500页,因此为了避免影响到大家的阅读体验,在此只以截图展示部分内容,详细完整版的可以在文末获取! 部分内容展示 深入浅出索引(上) 索引的常见模型 InnoDB 的索引 ...

  5. Java的Io模型你了解多少?工信部java证书

    算法 ⼏道常⻅的字符串算法题总结 最⻓公共前缀 回⽂串 两数相加 翻转链表 链表中倒数第k个节点 删除链表的倒数第N个节点 合并两个排序的链表 剑指offer部分编程题 跳台阶问题 变态跳台阶问题 ⼆ ...

  6. Java的Io模型你了解多少?linuxmysql安装位置

    正文 我的第一份工作是在一家外企,当时抱着"逃离"上海的想法去了二线城市的分公司,但是管理文化氛围跟总部几乎都是一样的,这份工作经历对我后面的工作不论是做事风格.习惯上还是思考问题 ...

  7. Linux/Unix五种IO模型

    文章目录 引入 操作系统的内核态和用户态 文件描述符fd IO操作过程: 阻塞和非阻塞 同步和异步 同步IO和异步IO 五种IO模型 1.(同步)阻塞IO模型 2.(同步)非阻塞IO模型 3.IO多路 ...

  8. 常见的 IO 模型有哪些?Java 中 BIO、NIO、AIO 的区别?

    IO 模型这块确实挺难理解的,需要太多计算机底层知识.写这篇文章用了挺久,就非常希望能把我所知道的讲出来吧!希望朋友们能有收货!为了写这篇文章,还翻看了一下<UNIX 网络编程>这本书,太 ...

  9. Java基础之IO模型

    Java基础之IO模型 I/O 常见的IO模型 Java中3种常见的IO模型 BIO(Blocking I/O) NIO(Non-blocking/New I/O) AIO(Asynchronous ...

最新文章

  1. 搜索引擎技术之概要预览
  2. MDI接口原理图设计
  3. java md5加密32位小写_Java生成MD5的方法,简单封装并转为32位小写
  4. 7 天玩转 ASP.NET MVC — 第 6 天
  5. 【笔记】css 自定义select 元素的箭头样式
  6. 第十六章:Java内存模型——Java并发编程实战
  7. MACOSX下查看某个端口被哪个程序占用及杀进程方法
  8. mysql炸包_炸裂!MySQL 82 张图带你飞
  9. JavaFX 概述 (译)
  10. Go基础:切片的地址和扩容
  11. 甘特图控件VARCHART XGantt如何开始使用
  12. python周环比增长率怎么算_Pandas实现计算同比、环比
  13. linaro 网站资源
  14. Ubuntu 14.04 解决 DNS 解析失败
  15. 2. 确定地球与金星之间的距离 天文学家在1914年8月份的7次观测中,测得地球与金星之间距离(单位:米),并取其常用对数值,与日期的一组历史数据如下表:
  16. 长期吃nmn有副作用吗,nmn产品副作用,真相说明
  17. 从零开始学WEB前端——JavaScript数据类型
  18. 计算机组装如何配置更好更便宜,电脑组装越贵越好?小白DIY组装电脑的几个误区...
  19. hadoop之旅8-centerOS7 : Hive的基本操作
  20. 汽车零部件行业困境及如何利用MES解决?

热门文章

  1. 牛客多校10 - Tournament(找规律)
  2. CodeForces - 1354D Multiset(线段树/二分)
  3. HDU - 3341 Lost's revenge(AC自动机+状压dp)
  4. python 逻辑回归权重_Python 逻辑回归
  5. java平均差_如何做好描述统计分析
  6. 14.IDA-XREF(交叉引用)概述
  7. 第一次使用OD和IDA动静结合找出软件的注册算法
  8. PostgreSQL学习笔记6之函数和操作符二
  9. 网络游戏外挂核心封包揭密
  10. 手把手教你玩转ARP包(三)