Java基础知识(6) - IO操作理论
IO操作一直是一个经久不衰的面试话题,其实IO的东西并不是特别多,唯一的难处在与它特别零散,各个知识点需要交叉起来学习,这样我们才会有感觉到收益。下面我们先从操作系统的IO模型讲起,最后到Java原生的IO模型。
操作系统的IO
操作系统的IO模型一共有五种,按照效率从低到高排列分别是:阻塞式、非阻塞式、信号驱动式、多路复用式和异步式。在深入探讨这五种模型之前,我们需要知道操作系统处理一次IO的过程,即:CPU将数据从磁盘拷贝到内核空间,再将内核空间的数据拷贝到用户空间以供应用程序使用。那么带着这个观点我们一起去看操作系统的五种IO模型。
-
阻塞式IO
阻塞IO的情况下,当应用程序发送read请求的后会一直阻塞,直到操作系统返回数据。在操作系统返回数据之前的这段时间里面,应用程序任何事情都不会做,会一直等下去。
-
非阻塞式IO
非阻塞IO的情况下,应用程序会一直发送read请求,直到内核数据准备好才开始阻塞。其实说白了非阻塞式IO下的应用程序也是阻塞的,但是它不是全程阻塞的,这也是它于阻塞式IO的区别。
-
信号驱动式IO
信号驱动式IO的情况下,应用程序会拥有一个回调函数,在内核空间数据准备好的时候开始调用,即它不会像非阻塞式IO那样一直轮询。
-
多路复用式IO
多路复用式IO的图如下,可能细心的读者会发现,这张图和上一张没有区别。但是多路复用IO最大的区别它是使用一个selector来管理多个应用程序,它的效率更加高效。linux中的实现有select、poll、epoll。
-
异步式IO
看了下面这张示意图,大家就会明白只有异步式IO才实现了真正的异步。应用程序全程都不会发生等待,上面的几种IO模型都只是最大程度上减少等待时间。
Java中提供的IO
Java提供的bio、nio、aio是帮助我们简化了调用操作系统这个环节。那么我们Java程序员经常说的IO语义和操作系统的有些不同,我们更加侧重于网络方面。那么这三种io模型分别对应服务器和客户端的三种交互模型,下面让我们一起学习三种IO模型。
-
同步阻塞式IO(bio)
这种模式下的C\S系统往往是一个线程对应一个客户端连接,服务器压力较大。我们通常使用InputStream和OutPutStream的流家族作为客户端和服务端连接的组件。
-
同步非阻塞式IO(nio)
这种模式下的C\S系统往往是一个线程对应多个客户端连接,服务器可承载的压力大大增加,适用于小数据量的交互。我们通常使用Selector、Channel和Buffer作为客户端和服务端连接的组件。
-
异步式IO(aio)
这种模式下的C\S系统往往是一个线程对应多个客户端连接,服务器可承载的压力和nio模式下的不相上下,但是它更加适用于大客户端的传输。