同步和阻塞大体上描述的是同一种行为,比如方法A调用方法B。方法A一定要等到方法B执行完毕后,再返回。在方法B执行过程中,方法A依然占用时间片,阻塞等待方法B执行完成。这种IO模型又叫BIO 即Blocking IO
方法A调用方法B后,立即返回,不阻塞。但方法B可能需要执行很长时间,如果想要拿到方法B执行后的结果,需要循环d定时的去查询方法B的执行情况,这个查询过程也是非阻塞的,调用后立即返回。当查询到方法B已经执行完成,则方法A再调用获取数据的方法,去拉方法B的执行结果。
这种IO模型又叫NIO 即Non Blocking IO
方法A调用方法B时,像非阻塞模式一样,也是立即返回,只是在调用时,需注册一个回调方法。然后方法B可能执行很长时间,但这个过程方法A不占用任何时间片。在方法B执行完毕后,主动调用之前注册的回调方法。
这种IO模型又叫AIO 即 Asynchronous IO
linux对所有资源都当做文件来看待,对一个资源的持久句柄,就是文件描述符。一个应用程序,读某个资源的访问,不是直接进行的。而需要通过linux内核来完成。内核在数据就绪时,会将内核空间中的数据拷贝至应用程序所在的用户空间,最后应用程序才能对数据进行后续处理。
应用程序在发起资源访问时,最耗时的两处是,一是等待资源数据就绪,二是将数据从内核空间拷贝到用户空间。这两处会造成阻塞。linux 的io模型的不同,即体现在这两步操作上。
需要多次调用recvfrom判断数据是否就绪,这些操作是非阻塞的。就绪后,再将数据从内核空间拷贝到应用进程所在的用户空间
比起上两种IO,多了一步select操作。select会阻塞直到数据就绪,这点跟阻塞IO类似。但不同的时,阻塞IO是对单个进程或线程阻塞。而select操作,是个多路复用器,多个进程或线程都可以通过它阻塞,并在任何资源就绪后返回。应用程序在select返回后,再通过recvfrom去将数据,从内核空间拷贝到应用程序的用户空间。select本身需要循环调用,以便随时监听后续的数据就绪事件。Java NIO的selector即是这种概念的实现
跟多路复用器IO类似,只是不是通过select来阻塞。而是通过signaction来注册信号响应函数来实现
这个同开篇讲的异步模型类似。
java中通过InputStream和OutputStream对资源访问的方式,就是阻塞式的
java并发操作时,返回的Future对象的get方法,也是阻塞的。
Java NIO中的通过buffer的方式读写,是非阻塞的。而Java NIO中selector,又属于一种多路复用器的技术。Java并发编程中Future对象的isDone方法,又可用在非阻塞编程中,进行轮巡获取任务执行状态。
典型的特点是,提交一个任务执行时,注册一个回调方法。提交任务执行的主线程不用等待任务执行结果,无需阻塞。任务执行完毕后,会自动执行回调方法。
Java中对异步模型的支持如下:
https://www.slideshare.net/liranbh/linux-io-72197884
http://timetobleed.com/io-models-how-you-move-your-data-matters/
http://www.cnblogs.com/LittleHann/p/3897910.html#top
https://wirelessr.gitbooks.io/working-life/content/io_model.html