虽然忙碌,但仍小有收获,开心。编程
BIO: Blocking IO,阻塞式IO缓存
NIO: Non-blocking IO,非阻塞式IO网络
AIO: Async IO,异步IO多线程
什么是阻塞式IO/非阻塞式IO,什么又是同步IO/异步IO呢?框架
① IO实际上分为两大步:应用程序请求的IO操做、操做系统的IO操做 - 用户空间和内核空间(kernel)。用户空间的应用程序须要IO操做,其实是调用的操做系统的IO操做。异步
② kernel的IO操做是须要时间的 - 姑且叫它准备时间吧。函数
那问题来了:在这个准备时间里,操做系统和应用程序都是如何工做的?性能
以应用程序读取数据为例(这里不考虑缓存),操做系统其实有两类回复:编码
① 等到须要的数据都准备完毕再回复 -- 中间一直默不做声,这就是同步IO。操作系统
② 先告诉应用程序数据没有准备好,而后准备好数据,通知(回调)应用程序或被轮询 -- 这就是异步IO。
那应用程序如何对待这个响应呢?其实仍是两类:
① 一直等,直接数据都发过来,而后再进行下一步。-- 阻塞IO。
② 先干别的,而后按期查询或等待回调。-- 非阻塞IO。
阻塞/非阻塞IO 说的是应用程序的IO操做;同步/异步IO 说的是操做系统的IO操做。
注意,异步、非阻塞,都有两个彼此对应的小分类。
前面已经说过,操做系统的IO操做分为同步IO和异步IO。同步IO没什么好说的,咱们就来看看异步IO。
异步IO,实际上是三个系统函数select、poll、epoll中的一个(跟Linux内核版本有关),搞C/C++编程的人应该熟悉这个。
虽然select和poll的性能极高,但能处理的数量有限制,没记错的话是不能超过1000个,不然性能下降。
epoll的性能略低(固然仍是很高),但能处理的数量很高。
这几年的Linux核心用的都是epoll,就是说新版本系统上 JDK NIO调用的是epoll。
感兴趣的人能够查阅相关资料了解下。
注意,这里说的操做系统都是指Linux。
查了一些资料,都是用网络编程为例来讲明BIO、NIO、AIO的区别,这里就再也不敲代码了,直接说说彼此的优缺点好了。
BIO:优势是编码简单,容易上手、调试。缺点则是由于多线程自己的问题,①每一个线程都要分配内存空间(最少128K),②线程的切换须要耗费时间。因此,一是线程数量有限;二是线程多了会严重下降响应时间。固然也可使用线程池,但又涉及到队列任务积压问题。
NIO:恰好跟BIO相反。优势是速度快,耗费资源少。缺点是编码复杂,难以上手、调试。
AIO:这个暂时没研究,不过想一想应该跟js的回调是一个道理。事件驱动(回调),性能高。
说到NIO,其实不多有直接使用JDK的NIO的,由于有严重bug,会致使Linux下select占用CPU 100%。虽然说后续有改进,但也只是下降了概率,并无完全消除。
因此建议使用Netty、Mina之类的框架,要好的多。
另外,Tomcat,自版本7开始,使用的就是NIO技术,以提高服务性能。