BIO:同步阻塞IO
NIO:同步非阻塞IO
AIO:异步非阻塞IO
关于阻塞和非阻塞
不管是文件IO还是网络IO,会阻塞的根本原因在于应用程序的用户空间和操作系统的内核空间的数据互相拷贝
文件IO
读取:需要将操作系统内核空间将数据准备好拷贝给应用程序的用户空间
写入:需要将应用程序的用户空间将数据准备好拷贝给操作系统内核空间
网络IO
接收网络请求:网络--》网卡--》内核空间--》用户空间
发送网络请求:用户空间--》内核空间--》网卡--》网络
阻塞IO
用户线程必须等待用户空间和内核空间之间的互相拷贝完成才能执行下一步
非阻塞IO
用户线程把请求提交给用户空间后不需要一直等着用户空间和内核空间完成互相拷贝完,它可以继续执行,当用户空间和内核空间完成互相拷贝之后通知用户线程获取数据
BIO与NIO区别
BIO通常不知道什么时候能够读写,并且读写线程不能共用,只能傻等,最好的方式就是起线程另起炉灶,但在linux中线程本质是进程创建、销毁线程的代价很高昂,如果线程数量过高,会导致线程切换的时间高于线程执行时间,带来的现象就是系统的load偏高导致系统几乎不可用,容易造成锯齿状的系统负载,因为系统负载是用活动线程数或CPU核心数,一旦线程数量高但外部网络环境不是很稳定,就很容易造成大量请求的结果同时返回,激活大量阻塞线程从而使系统负载压力过大。
NIO本质上是通过统一的Selector管理(通过注册需要的读写,从channel通道中轮询获取请求)达到单线程就能处理不同的读写操作,从而达到减少线程创建、销毁的数量,增加cpu的有效利用率(实际执行IO读写,而不是线程切换)
NIO与AIO的区别
从编程模式上来看AIO相对于NIO的区别在于,NIO需要使用者线程不停的使用Selector轮询所有的IO对象,来确定是否有数据准备好可以读了,而AIO则是在数据准备好之后,才会通知数据使用者(专门的Selector线程来轮询),这样使用者就不需要用Selector线程不停地轮询了。当然AIO的异步特性并不是Java实现的伪异步,而是使用了系统底层API的支持,在Unix系统下,采用了epoll,IO模型,而windows便是使用了IOCP模型
不同平台下采用轮询的方式
Linux下NIO、AIO采用Linux的epoll来轮询,windows下NIO、AIO采用IOCP的形式轮询
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。