java的I/O面试:BIO、NIO 和 AIO 这三者的区别

怎么理解BIO、NIO、AIO?

  • BIO: 同步阻塞IO。当有连接的时候,就算连接没有传输数据,线程的CPU资源也会被占用,相当于没有活干的时候,打工仔也一直守在客户现场.

服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器需要启动一个线程进行处理

每个连接会占用一个独立的线程,因此,如果有大量的并发请求,会创建大量的线程,线程上下文切换和内存消耗导致系统性能下降。

工作流程:
  1. 客户端连接到服务器时,服务器为每个客户端请求创建一个线程。
  2. 每个线程处理一个请求,当一个线程在处理 I/O 操作时,它会被阻塞,直到 I/O 操作完成。
  3. 阻塞的线程不能做其他事情,直到当前的请求完成。

示例代码Be Like:

// 服务端使用BIO模型
ServerSocket serverSocket = new ServerSocket(8080);
while (true) {
    // 接受连接并为每个连接启动一个线程
    Socket clientSocket = serverSocket.accept();
    new Thread(new ClientHandler(clientSocket)).start();
}
  • NIO: 同步非阻塞IO。和BIO的区别是,连接后监听工作不是由线程去监听了,而是由一个同一个中介人Selector选择器不停的轮询各个通道是否由数据传输.类似于本来每个员工必须等待各自客户的回复,但是现在统一由一个中介承包了,当一个客户有需要的时候这个中介才通知相应的员工干活.

服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有IO请求时才启动一个线程进行处理。用户进程也需要时不时的询问IO操作是否就绪,这需要用户进行不停的去询问。NIO的包括三个核心概念: 缓冲区(Buffer)、通道(Channel)、选择器(Selector)。

主要特点: 

  1. 同步非阻塞:NIO 主要通过 非阻塞 I/O 和 多路复用(select 或 poll)来优化性能。在 NIO 中,线程和 I/O 操作是非阻塞的,线程不会被阻塞等待 I/O 完成,而是可以处理其他任务。
  2. 单线程多连接:NIO 引入了 选择器(Selector),一个线程可以通过选择器同时管理多个通道(Channel)。这使得可以通过少量线程来处理大量的客户端请求。

多路复用:使用 Selector 来轮询多个通道。线程可以在一个通道上执行 I/O 操作时,检查其他通道的状态,避免每个请求单独占用一个线程。

非阻塞操作:每个 I/O 操作不会阻塞线程,线程可以处理其他任务。

优点:解决了 BIO 的线程开销问题,减少了内存消耗和线程上下文切换

适用场景:适用于 短连接 或 连接数非常多的场景

  •  AIO:异步非阻塞 I/O.相当于甲方程序员把事情外包出去了给同一个外包公司,然后甲方程序员忙自己的去了,等外包公司异步的把活干完,自己等他们回应就行了

AIO 是完全 异步非阻塞 的 I/O 模型,所有的 I/O 操作(如读写文件或网络)都由操作系统(OS)来处理,程序员不需要主动去等待 I/O 操作完成

 线程会发起 I/O 请求,然后立即返回,不会被阻塞。操作系统会在 I/O 完成时通知应用程序,应用程序可以通过回调函数或者 Future 对象来处理结果

优点:
  • 完全的异步处理,无需阻塞线程,减少了上下文切换。
  • 极高的并发性能,适用于 连接数非常多 的场景,特别是需要 长连接 的场景。
  • I/O 操作交由操作系统处理,线程池管理也更加轻松,减少了资源消耗。

代码示例:

AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open();
serverSocketChannel.bind(new InetSocketAddress(8011));
 
serverSocketChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {
    @Override
    public void completed(AsynchronousSocketChannel result, Void attachment) {
        // 处理连接...
        serverSocketChannel.accept(null, this); // 继续接受新的连接
    }
 
    @Override
    public void failed(Throwable exc, Void attachment) {
        exc.printStackTrace();
    }
});
适用场景:
  • 连接数非常多且连接持续时间较长 的场景,例如 视频流服务文件上传/下载 或 长连接的即时通讯服务

场景总结:

  • BIO:适合低并发、小型应用,开发简单,但性能较差。
  • NIO:适合高并发场景,尤其是短连接,性能更高,但编程复杂。
  • AIO:适合非常高并发且长连接的应用,性能极佳,但开发复杂且对操作系统支持要求高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值