面试中常问的Java IO模型到底是什么?

本文详细介绍了Java中的四种IO模型:同步阻塞IO(BIO)、同步非阻塞IO(NIO)、IO多路复用以及异步IO(AIO),并提供了相关代码示例。主要内容包括BIO的工作原理、NIO的使用、Java和Linux中IO多路复用的区别以及AIO的特点。
摘要由CSDN通过智能技术生成

最近在面试中常常被问到IO模型,于是想在网上找找对应的讲解,可都没有一个详细好理解且带例子的。下面会介绍Java的几种IO模型,并且均给予代码演示。

Java中最常用的模型个人认为有以下四种:

  • 同步阻塞IO(Blocking IO)
  • 同步非阻塞IO(Non-Blocking IO)
  • IO多路复用
  • 异步IO(Asynchronous IO)

一、同步阻塞IO(BIO)

同步阻塞IO可以说是最简单的了,就是如果目标是不可读/写的话,那么就阻塞当前进程,直到目标可读/写

下图以read方法举例BIO:
在这里插入图片描述
图中的kernel指的是系统内核。当数据准备好时,会将数据从内核拷贝到进程中,这也就完成了读的操作。
在Linux中,网络IO默认的方式就是BIO。

下面以Java网络编程为例,写一段Server从Socket中读取Client的输入的代码:

//这是服务端类,会读取socket中的数据
public class Server {
   
    public static void main(String[] args) {
   
        try {
   
            ServerSocket serverSocket = new ServerSocket(11522);
            Socket socket = serverSocket.accept();
            System.out.println("客户端已连接 at "+System.currentTimeMillis());
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
            int read = ois.read(); //线程会在这里阻塞住
            System.out.println("阻塞结束,读到数据:"+read+" at "+ System.currentTimeMillis());
            ois.close();
            socket.close();
        } catch (IOException e) {
   
            e.printStackTrace();
        }
    }
}
//这是客户端类
public class Client {
   
    public static void main(String[] args) {
   
        try {
   
            Socket socket = new Socket("127.0.0.1", 11522);
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            Thread.sleep(2000);	//在等待两秒后才写入数据
            oos.write(32);
            oos.close();
            socket.close();
        } catch (IOException | InterruptedException e) {
   
            e.printStackTrace();
        }
    }
}

程序运行结果如下,从中可以明显看出,Server线程阻塞了2秒。
在这里插入图片描述

二、同步非阻塞IO(NIO)

同步非阻塞IO其实就是一种轮询,当数据还没有准备好的时候,不再阻塞而是直接返回一个error。然后线程再次发起请求,直到数据可读为止。然后再将数据从内核拷贝到进程中,完成读操作。

在这里插入图片描述
这里要说一下,Java中有个包叫java.nio。但其实,其实现方式采用的是IO多路复用的原理,这个在下面会讲。

三、IO多路复用

个人认为多路IO复用是NIO的一种实现形式(个人认为)。IO多路复用可以说面试问得最多,也很常见。

1.Java中的IO多路复用

Java中的IO多路复用就是使用java.nio包下的Buffer、Channel、Selector来实现的。首先说一下它们的概念:

  • Buffer,顾名思义是一个缓冲区,是由一个数组实现的,存储的是在Channel中传输的数据。
  • Channel,可以类比于流一样的东西,通过这个可以实现Channel双方的通信。在网络编程中,可以使用SeverSocketChannel、SocketChannel来代替SeverSocket、Socket。
  • Selector,实现IO多路复用最关键的类,通过它可以获取当前注册进Selector的Channel的状态。

具体的原理和使用方法,可以详见博客:https://www.cnblogs.com/snailclimb/p/9086334.html。里面讲的非常清楚。

下面给出一段服务端的代码,其中做了较为详细的注释:

public class WebServer {
   
    public static void main(String[] args) {
   
        try {
   
            ServerSocketChannel ssc = ServerSocketChannel.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值