Bio、Nio与Aio区别整理
IO:即输入(Input)和输出(Output)
阻塞:当试图对该文件描述符进行读写时, 如果当时没有东西可读,或者暂时不可写, 程序就进入等待 状态, 直到有东西可读或者可写为止(强迫症,必须这件事做完才能做其他事情,否则一直等待)
非阻塞: 如果没有东西可读, 或者不可写, 读写函数马上返回, 而不会等待。(先取号,可以去做其他事情,叫号后,过来完成该事情)
同步:指的是用户进程触发IO操作并等待或者轮询的去查看IO操作是否就绪(亲力亲为且专注于一件事)
异步: 异步是指用户进程触发IO操作以后便开始做自己的事情,而当IO操作已经完成的时候会得到IO完成的通知(异步的特点就是通知,Java将IO读写委托给OS处理,需要将数据缓冲区地址和大小传给OS)即:指示别人帮自己做事,完成后得到通知
Bio、Nio和Aio三者比较
名称 |
说明 |
应用场景 |
补充 |
优点 |
缺点 |
Bio |
阻塞io |
Apache,Tomcat。主要是并发量要求不高的场景 |
连接数目比较小且固定的架构 |
模型简单、 编码简单、 |
性能瓶颈低、不适合高并发 |
Nio |
同步非阻塞io |
Nginx,Netty。主要是高并发量要求的场景 |
连接数目多且 连接比较短(轻操作)的架构 |
性能瓶颈高 |
模型复杂、 编码复杂、 需处理半包问题 |
Aio |
异步非阻塞io |
还不是特别成熟,底层也基本是多线程模拟,所以应用场景不多,Netty曾经用了,但又放弃了。 |
连接数目多且连接比较长(重操作)的架构 |
|
|
假设有这么一个场景,有一排水壶(客户)在烧水。
AIO的做法是,每个水壶上装一个开关,当水开了以后会提醒对应的线程去处理。
NIO的做法是,叫一个线程不停的循环观察每一个水壶,根据每个水壶当前的状态去处理。
BIO的做法是,叫一个线程停留在一个水壶那,直到这个水壶烧开,才去处理下一个水壶。
可以看出AIO是最聪明省力,NIO相对省力,叫一个人就能看所有的壶,BIO最愚蠢,劳动力低下。
进程中的IO调用步骤:
- 进程向操作系统请求数据 ;
- 操作系统把外部数据加载到内核的缓冲区中;
- 操作系统把内核的缓冲区拷贝到进程的缓冲区 ;
- 进程获得数据完成自己的功能 ;
当操作系统在把外部数据放到进程缓冲区的这段时间(即上述的第二,三步),如果应用进程是挂起等待的,那么就是同步IO,反之,就是异步IO,也就是AIO 。
Nio与Aio的区别?
AIO是发出IO请求后,由操作系统自己去获取IO权限并进行IO操作;NIO则是发出IO请求后,由线程不断尝试获取IO权限,获取到后通知应用程序自己进行IO操作。
AIO只是帮助你从内核中将数据复制到用户空间中,并调用你传入的回调方法。
NIO 是需要程序自己从内核中将数据复制到用户空间中,并需要程序自己调用相应的处理逻辑。
Nio线程处理流程
其他补充:
1、系统并发量很大,容易出什么问题?
答:内存溢出,cpu处理不过来。
1.132位系统1个线程对象默认最大需要320kb内存,64位系统默认需要1M内存,业务对象还需要内存,容易造成内存不够。
1.2过多的线程需要os频繁切换,也大大影响性能。
1.3Java的new一个对象,调用操作系统的api,都存放在java的堆里。线程创建时有个栈空间,会消耗内存。
参考:1、https://juejin.im/entry/598da7d16fb9a03c42431ed3
2、https://www.cnblogs.com/doit8791/p/4951591.html
3、https://www.jianshu.com/p/901a6e35b3d9
4、https://www.cnblogs.com/ygj0930/p/6543960.html
5、https://juejin.im/entry/598da7d16fb9a03c42431ed3
6、https://blog.****.net/jijianshuai/article/details/77450746