BIO&NIO&AIO模型快速实战
BIO 同步阻塞IO
大白话介绍
- 一次只能处理一个连接,BIO它的连接和读数据都是阻塞的。
理论介绍
- 同步阻塞,服务器实现模式一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销。
弊端:
- 阻塞 (最大问题,如果处理500个请求,但是有499个没有给我返回数据,那么我就一直在这阻塞住了)
- 并发效率低(一次只能处理一个请求)
- 线程太多了(因为你每发来一个请求都会去开一个线程,那么如果这个时候过来100万个请求那么就需要开100万个线程,服务器怎么可能抗的住)
代码介绍
- 首先建立客户端连接
- socket.accept()监听客户端连接
- 如果没有人来连接,那么就会一直卡在这里,直到有人来连接才会往下走
- 获取他的输入输出流,获取到后存放一个空间里面,存到数组里面
- 使用读的流把数据读出来,如果有一个客户端连接上我这个服务器
- 但是并不给我这个服务器发消息
- 然后我们这个服务就会一直卡在这里,然后客户端连接的哪个代码就永远得不到执行了
- 直到这个客户端给我们服务端发来消息,然后服务端才能去接收下一条消息
BIO开的线程太多了 NIO就是解决这个问题!!!
BIO是怎么延伸到NIO的?
- NIO它把两个阻塞的方法accept()和rend()给改掉了,改成非阻塞的方法
- 防止没有人来连接,也一直在跑浪费性能的问题上呢我们增加一个list集合
- 然后如果有请求进入了 才去添加到list集合中去,然后到时候直接遍历list集合就能去看我们请求了
NIO 同步非阻塞
大白话介绍
- 设置configureBlocking()方法为非阻塞状态
- 就算到时候接受不到发来的数据,那么NIO也不会阻塞
理论介绍
- NIO 同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到 多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。用户进程也 需要时不时的询问IO操作是否就绪,这就要求用户进程不停的去询问
弊端:
NIO单线程的缺点:
性能太慢了,一个线程处理不过来。如果发送10000个请求,每个请求逗得经历编码解码之类的操作,那性能太慢了。
代码分析
- 首先打开一个选择器对象selector
- selector专门用来存放socket的
- 然后打开一个服务端
- 设置configureBlocking()方法为非阻塞状态
- 然后把socket添加到集合当中和绑定连接事件
- 如果一旦有客户端连接我了,那就能触发连接事件
- 然后到时候通过调用select()方法查看是否有事件发生,如果有则把这个事件加入集合当中,继续执行
- 遍历集合看看有没有事件发生
*BIO不知道什么时候有人来连接它,也不知道什么时候能发来消息,但是NIO改变了这个思路,它是倒着过来的NIO只给某个对象指定事件,一旦有事件发生了就告诉我,由操作系统告诉我。
AIO
理论介绍
- AIO 异步非阻塞,在此种模式下,用户进程只需要发起一个IO操作然后立即返回,等IO 操作真正的完成以后,应用程序会得到IO操作完成的通知,此时用户进程只需要对 数据进行处理就好了,不需要进行实际的IO读写操作,因为真正的IO读取或者写入 操作已经由内核完成了
BIO、 NIO、AIO适用场景分析
- BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高, 并发局限于应 用中,JDK 1.4以前的唯一选择,但程序直观简单易理解。
- NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK 1.4开始支持。
- AlO方式使用于连接数目多且连接比较长(重操作) 的架构,比如相册服务器,充分调用OS参与并 发操作,编程比较复杂,JDK 7开始支持。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了