工作这么久了,还不懂网络I/O模型吗?
1、I/O模型说明
I/O模型你可以简单的理解成:用什么样的通道进行数据的发送和接收,很大程度上决定了程序通信的性能。比如后面会讲解到的BIO使用流的形式,NIO给予Buffer缓冲等
Java共支持3种I/O模型,BIO(同步阻塞),NIO(同步非阻塞),AIO(异步非阻塞)
-
阻塞:主要是指访问IO的线程是否会阻塞(或处于等待),比如客户端发起一次请求,该请求要先请求redis,然后再请求数据库,阻塞就意味着:我请求redis之后,再redis没有返回数据之前,Thread-A是不能继续往下走的,也就是不能去访问数据库的,它必须等到redis返回数据之后才能继续往下走
-
非阻塞:主要是指访问IO的线程它不会被阻塞或等待,它会在等待的这段时间去做别的事,比如:客户端先请求redis,Thread-A不会等到redis数据返回之后才继续往下走,它在请求redis之后,不管redis有没有返回结果,它直接就继续往下走哪了,也就是直接去请求数据库了。也就是说它不会等到redis数据准备就绪之后才访问数据库
- 同步:当线程去请求一个资源,必须等到资源准备就绪之后,然后再返回,也就是说在资源准备的这段时间,线程是处于等于状态的
- 异步:当线程去请求一个资源,线程不会去等待资源准备就绪,而是会通过回调的方式将结果返回
2、同步阻塞BIO
Java BIO就是传统的Socket编程,服务器模式就是当客户端发起一个连接请求之后,服务器就需要创建一个新的线程去处理,也就是1对1的模式,如果这个线程不做任何的业务处理,那么就会造成资源的浪费,服务器端可以使用线程池机制来改善
- BIO工作机制:客户端发起一个请求连接,服务端就需要创建一个新的线程去处理该客户端的请求
-
BIO问题分析:
1: 每个请求都需要创建一个新的线程与对应的客户端进行数据的读写
2: 并发数较大时候,服务端需要创建大量的线程,系统资源占用大
3: 连接建立后,如果当前客户端没有数据读取,那么该线程就会阻塞,造成资源的浪费
3、同步非阻塞NIO
同步非阻塞,服务器实现模式一个线程处于多个连接请求,然后将对应的客户端注册到多路复用器上,多路复用器会轮询到有IO事件的请求就会进行处理
客户端发起连接请求,服务端发现这是一个连接请求,那么就会将该客户端注册到Selector选择器上,然后Selector选择器会轮询所有的客户端,如果有客户端发起了读写请求,那么就会被交给对应的线程去处理,如果没有就直接等待下一次轮询。相比于BIO,NIO不会是一个客户端连接请求就创建一个线程了,只有真正有IO事件的时候才会交给对应的线程去处理
4、异步非阻塞AIO
AIO 引入异步通道的概念,采用了 Proactor 模式,简化了程序编写,有效的请求才启动线程,它的 特点是先由操作系统完成后才通知服务端程序启动线程去处理,一般适用于连接数较多且连接时间较长的应用
Proactor 模式是一个消息异步通知的设计模式,Proactor 通知的不是就绪事件,而是操作完成事件,这也就是操作系统异步 IO 的主要模型。
5、BIO/NIO/AIO适用场景
- BIO(同步并阻塞): 适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序简单易理解
- NIO(同步非阻塞): 适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,弹幕系统,服务器间通讯等。编程比较复杂,JDK1.4 开始支持
- AIO(异步非阻塞): 适用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用 OS 参与并发操作, 编程比较复杂,JDK7 开始支持。
作者:我想涨工资
链接:https://juejin.cn/post/7096664570579648525
来源:稀土掘金