java从程序从网络中读取一组数据,首先从用户态发出IO请求,申请系统调用。操作系统内核收到系统调用,执行对应的IO操作。
1.首先由DMA从网卡缓存区将数据拷贝到系统的内核缓冲区。
2.再由内核讲内核缓存区的数据拷贝到用户态的用户缓冲区当中。此时,数据拷贝完成依次返回。
这个过程中存在这么几个步骤,第一,用户态发起IO请求。第二内核态执行IO具体的读写操作。(基于这两个部分谈同步和阻塞的概念)
1.用户态发起IO请求如果一直等待数据,那么叫阻塞。用户在发起IO请求后直接返回,叫非阻塞。
2.而对于系统内核线程,执行IO具体的读操作的时候,如果一直等待则叫同步。如果不等待直接返回则叫异步。
异步行为往往需要操作系统内核,通知应用程序,所以需要操作系统深度参与。只有在高版本的Linux发行版本中才支持。
BIO叫同步阻塞IO
应用程序从用户态发起IO申请,阻塞;而内核态执行IO操作同步。所以BIO叫同步阻塞IO。
nio同步非阻塞IO
应用程序发起IO申请之后,应用程序直接返回叫非阻塞。而操作系统内核仍然采用同步的方式,进行数据IO。非阻塞的应用程序,可以使用轮询的方式(用户态),进行数据探测。
AIO异步非阻塞式的IO模型
应用程序发起IO申请之后,应用程序直接返回叫非阻塞。操作系统内核采用异步的方式进行IO操作。IO结束之后,需要由于操作系统内核,通知应用程序。AIO是理想的完美解决方案,但是支持他的系统版本不多。
最流行的是IO多路复用
这也是同步IO,它只是将轮询的操作,由用户态转到了内核态。由操作系统,提供一系列可调用的系统调用函数,实现IO多路复用。本质上,是阻塞一个线程,实现类似异步调用的操作。
相当于10个人排队,吃饭,留下来一个人排队,其他的爱干啥干啥。排到了,这个线程去通知其他线程。java的NIO是基于IO多路复用实现的。Netty是一种封装实现。