美文网首页Java 程序员JavaJava
工作这么久了,还不懂网络I/O模型吗?

工作这么久了,还不懂网络I/O模型吗?

作者: 马小莫QAQ | 来源:发表于2022-05-12 15:40 被阅读0次

    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适用场景

    1. BIO(同步并阻塞): 适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序简单易理解
    2. NIO(同步非阻塞): 适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,弹幕系统,服务器间通讯等。编程比较复杂,JDK1.4 开始支持
    3. AIO(异步非阻塞): 适用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用 OS 参与并发操作, 编程比较复杂,JDK7 开始支持。

    作者:我想涨工资
    链接:https://juejin.cn/post/7096664570579648525
    来源:稀土掘金

    相关文章

      网友评论

        本文标题:工作这么久了,还不懂网络I/O模型吗?

        本文链接:https://www.haomeiwen.com/subject/lhzsurtx.html