摘要
在高性能的IO体系设计中,有几个名词概念常常会使我们感到迷惑不解,什么是IO?什么是NIO?什么是AIO?要了解这些,首先要了解同步、异步、阻塞、非阻塞,然后将其结合起来,了解IO、NIO、AIO就容易多了。
正文
同步与异步(synchronous/asynchronous):同步是一种可靠的有序运行机制,当我们进行同步操作时,后续的任务是等待当前调用返回,才会进行下一步;而异步则相反,其他任务不需要等待当前调用返回,通常依靠事件、回调等机制来实现任务间次序关系。
同步/异步:数据如果尚未就绪,是否需要等待数据结果。
阻塞/非阻塞:进程/线程需要操作的数据如果尚未就绪,是否妨碍了当前进程/线程的后续操作。
阻塞与非阻塞:在进行阻塞操作时,当前线程会处于阻塞状态,无法从事其他任务,只有当条件就绪才能继续,比如ServerSocket新连接建立完毕,或者数据读取、写入操作完成;而非阻塞则是不管IO操作是否结束,直接返回,相应操作在后台继续处理。
1)IO流(同步阻塞,适用于连接数目比较小且固定的架构)
同步并阻塞,服务器实现模式为一个连接一个线程,每个线程亲自处理io并且一直等待io的完成,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。
IO的局限:IO是面向流的,阻塞式的,串行的一个过程。对每一个客户端的socket连接,IO都需要一个线程来处理,而且在此期间,这个线程一直被占用,直到socket关闭。在这期间,tcp的连接、数据的读取、数据的返回都是被阻塞的。也就是说这期间大量的浪费了cpu的时间片和线程占用的内存资源。
每建立一个Socket连接时,同时创建一个新线程对该Socket进行单独通信(采用阻塞的方式通信)。这种方式具有很高的响应速度,并且控制起来也很 简单,在连接数较少的时候非常有效,但是如果对每一个连接都产生一个线程的无疑是对系统资源的一种浪费,如果连接数较多将会出现资源不足的情况。
2)NIO(同步非阻塞,适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中):三个主要组成部分:Channel(通道)、Buffer(缓冲区)、Selector(选择器)
解释下什么是同步非阻塞:再品味一下上边的解释好吧,同步是说我这个调用没返回,等到有结果了我再返回,而非阻塞是说我这个线程被挂起来了,可以去干点别的事,一旦准备好了,我的调用再返回,明白了没。
服务器实现模式为一个请求一个线程,每个线程亲自处理io,但有另外的线程轮询检查是否io准备完毕,不必等待io完成,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。
Channel:可以看做是IO中的流,但是是双向的,异步读写,必须通过Buffer对象;
Buffer:它包含一些要写入或者读到Stream对象的;
Selector:是一个对象,它可以注册到很多个Channel上,监听各个Channel上发生的事件,并且能够根据事件情况决定Channel读写。
3)AIO(异步非阻塞,连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作)
异步非阻塞,就只解释下异步,异步就是说我干脆都不等你结果了,直接返回,你有结果了你通知一下我就行。
异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理,每个线程不必亲自处理io,而是委派os来处理,并且也不需要等待io完成了,如果完成后,os会通知的。
作者:王策
来源:51Testing软件测试网原创