IO中的阻塞、非阻塞、异步、同步

1 先贴大神的博客

linux中的IO模型:
https://mp.weixin.qq.com/s/fVpb1R0o2knXh3_uZeaQBA

java中的IO模型:
https://mp.weixin.qq.com/s/Csi_ySQxoZ3YfpkkMwv9Ig


2 IO的基本流程:

所有的java的IO模型都是基于操作系统的IO模型实现的,以linux操作系统为例
如果有代码 File file = FileUtil.read.("/data/img.jpg"),实际的流程是这样的:
(1)应用程序向操作系统发起读文件调用
(2)应用程序根据操作系统返回的可读条件,执行同步阻塞等待或者非阻塞继续往下执行(被立即告知了成功或者失败)
(3)应用程序同步将拷贝数据到用户空间或者操作系统异步把数据拷贝到用户数据空间,并通知用户

3 linux的IO模型:

3.1 阻塞IO
应用获取数据可读条件是阻塞的;
数据准备好后,应用复制数据到用户空间是同步的

3.2 非阻塞IO
应用获取数据可读条件是非阻塞的(轮询数据是否准备好),轮询之间可以做其它事;
数据准备好后,应用复制数据到用户空间是同步的

3.3 信号驱动IO
应用获取数据可读条件是非阻塞的,应用会向内核注册一个信号处理函数,然后返回,干其它事情,当数据准备好后,内核通知应用;
数据准备好后,应用复制数据到用户空间是同步的

3.4 IO复用模型
应用获取数据可读条件是阻塞的,应用将所有的IO注册到一个select上,这个select会监听所有的注册IO。当应用调用select时,如果至少有一个IO的数据准备好了,返回可读条件,否则阻塞;
数据准备好后,应用复制数据到用户空间是同步的

3.5 异步IO模型
应用发起aio_read,告诉操作系统数据缓冲区、缓冲区大小、数据准备好后如何通知系统;操作系统搜到aio_read后,立即返回,应用干自己的事情了;当数据准备好后,操作系统自动把数据复制到应用指定的用户空间,然后通知应用。
这种属于异步非阻塞的。

4 java的IO模型

java中的阻塞、非阻塞
A调用B,A没有立即且明确地拿到B返回的成功、失败,一直等待B的返回,什么事情也不干,那么A就是阻塞的。
A调用B,A能够立即明确拿到B返回的成功、失败。那么A是非阻塞的。(比如失败了,IO数据没准备好,我们可以下次再来,B你总得告诉我不行啊,不能吊着A啊)

总结:阻塞和非阻塞讨论的是调用方A能立即且明确的拿到被调用方B返回的结果

java中的同步、异步
A调用B,如果B的处理是同步的,则B在处理完成后,才会明确通知A;
如果B是异步的,B会立即返回,告知A我已经收到请求了(仅仅告知B知道了),等处理完成后,再通知A。核心区别是B与A的交互是1次还是2次。例如支付中的回调就是典型的异步处理

总结:同步异步指被调用方B的行为:是立即返回知道了,等活干完了再异步通知;还是你给我等到,等活干完了一次性通知

个人觉得:

(1)同步阻塞IO存在(最常见,性能最差)
(2)异步阻塞IO存在
(3)异步非阻塞IO存在(最理想)
(4)同步非阻塞IO不存在!因为非阻塞要求被调用方立即返回成功或者失败,同步有要求被调用方会把耗时事情干完后,一次性通知调用方,所以矛盾的

猜你喜欢

转载自blog.csdn.net/ShuaiFanPi/article/details/82118426