一、什么是IO?
IO :输入 (Input)和输出(Output) ,是指与外部组件(如文件、网络连接、控制台等)进行数据交换的过程。
在讲这三者的区别的时候,先记住这三个代表--客户端、请求线程、服务器端。
接下来我将它们都赋予一个容易记住的角色,客户端:饭店的客户、请求线程:服务员、服务器端:厨师。
二、BIO
BIO(Blocking l/O): 传统的 java.io 包,它是基于流模型实现的,交的方式是同步、阻塞方式,也就是说在读入输入流或者输出流时,在读写动作完成之前,线程会一直阻塞在那里,它们之间的调用是可靠的线性顺序。它的优点是代码比较简单、直观;缺点是IO的效率和扩展性很低,容易成为应用性能瓶颈。
同步阻塞(Synchronous Blocking) : 在同步阻塞模型中,当一个线程请求执行I/O 操作时,它将被阻塞(暂停),直到操作完成为止。在此期间,线程不能执行其他任务,只有在操作完成后,线程才会继续执行。这是传统的 I/O 操作方式,当数据准备好后才会返回结果。
客户(客户端)去饭店点餐,厨师(服务器)会派服务员(请求线程)去接待客户,每来一个客户就要派出一个服务员去接待。
同步 体现在:限制了客户的行动。在菜还没做完的时候,客户不能去做别的事情,只能等厨师把菜做完才能去做别的事情。
阻塞 体现在:一个服务员只能服务一个客户,没上完菜的时候只能等待,只有这个客户服务完才能去服务别的客户。
三、NIO
NIO (Non-blocking l/O) : Java 1.4引入的 java.nio 包,提供了 Channel、Selector、 Buffer 等新的抽象,可以构建多路复用的、同步非阻塞IO 程序,同时提供了更接近操作系统底层高性能的数据操作方式。
同步非阻塞(Synchronous Non-blocking): 在同步非阻塞模型中,线程在请求 I/O 操作时不会被阻塞,但是它需要主动地轮询(polling)来检查操作的状态,线程会主动地询问操作是否就绪,如果就绪则执行操作,否则继续轮询。这种方式不会阻塞线程,但需要不断地轮询,可会浪费 CPU 资源。
BIO的模型里面,每次有新的客户过来,就要有新的服务员去服务,很浪费,NIO改进了这里,让一个服务员去服务所有客户,这个服务员会定期去看看厨师的菜做完没有。
多路复用 就体现在:一个服务员服务多个客户。
非阻塞 就体现在:服务员不会再等待,而是定时轮询去服务。
四、AIO
AIO (Asynchronous I/O) : Java 1.7之后引入的包,是 NIO 的升级版本,提供了异步非堵塞的IO 操作方式,因此人们它 AIO(Asynchronous IO),异步IO是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。
异步非阻塞 (Asynchronous Non-blocking) :在异步非阻塞模型中,线程请求执行I/O 操作后,可以继续的执行其他任务无需等待操作完成。当操作完成时,系统会通知线程,线程会处理完成的操作,异步操作通常通过回调函数或事件驱动的方式来处理,线程不需要主动轮询或等待。
AIO这里又是NIO的升级,此时它不再限制客户一定要等菜上完,客户可以去做其它事情。厨师的菜做完会通知客户。
异步 体现在:客户不再要求等待,可以去做别的事情。