同步/异步/非阻塞/阻塞

同步 v.s. 异步

关注的是消息通信机制(Synchronous communication/ Asynchronous communication),同步是指调用方法的时候,一直等待直到这个被调用的方法返回

同步

用户进程触发IO操作,并等待或轮询查看IO是否就绪

异步

用户进程触发IO后,该进程可以做其他事,当IO已完成后会通知该进程(异步的特点)

  • 使用异步IO,JAVA将IO读写委托给OS处理,同时需要将数据缓冲区地址和大小传给IO

阻塞 v.s. 非阻塞

针对IO操作的就绪状态采用不同的方式,阻塞是指请求资源没有准备好的时候阻塞请求的线程,直到操作系统把资源准备完毕,才会恢复这条线程继续IO操作

阻塞

如果程序试图对文件进行读写操作,但是并没有可进行的东西,那么此时程序一直进入等待状态

非阻塞

没有东西可读写,立即返回,不会进入等待状态;非阻塞是指请求的资源没有准备好的时候不要阻塞请求的线程,线程会继续往下执行

组合

同步阻塞—顺序执行

当系统调用read()时,app会阻塞并对内核进行上下文切换。然后触发读操作,当响应返回时(例如数据从一个读取的设备中返回),数据被移动到用户空间的缓存中。最后app就会解除阻塞(read()调用返回)

同步阻塞IO模型

同步非阻塞—轮询

在上一个同样的场景下,设备以非阻塞的形式打开,这意味着在IO未完成时,read操作可能会返回一个错误代码直到真正有数据返回,这样会浪费一些CPU资源

典型的应用是java NIO 1.0,通过轮询注册到selector里的socketchannel进行处理,如果没有可操作的资源,也不会阻塞。此时Selector基于select/poll模型实现,直到JDK1.7提供了NIO2.0,新增了异步的套接字通道NIO才是真正的异步IO:在异步IO操作的时候可以传递信号变量,当操作完成之后会回调相关的方法,异步IO也被称为AIO

同步非阻塞IO模型

异步非阻塞—委托完成

处理与IO重叠进行的模型,read请求会立即返回(说明read请求已经成功发起了),在后台完成读操作时,app会执行其他处理操作。当read的响应到达时,会产生一个信号/执行一个基于先从的回调方法来完成这个IO处理过程(注意与同步非阻塞不同,同步非阻塞虽然会立即返回结果,但是一直在轮询是否有正确数据返回,会浪费一些 )

异步非阻塞IO模型

参考

1.怎样理解阻塞非阻塞与同步异步的区别?