Java IO模型详解
创始人
2024-05-23 21:42:55
0

文章目录

    • Java IO模型详解
      • 一、I/O的定义
        • 1、计算机结构的视角
        • 2、应用程序的视角
      • 二、Java 中3种常见的 I/O 模型
        • 1、同步阻塞 I/O(BIO)
        • 2、同步非阻塞 I/O(NIO)
        • ★ I/O 多路复用模型
        • 3、异步非阻塞 I/O(AIO)

Java IO模型详解

一、I/O的定义

I/O 是 Input/Output 的首字母缩写,即输入/输出,它描述的是数据流动的过程。输入/输出是相对而言的。下面将从两个角度出发来进一步理解 IO:

1、计算机结构的视角

在这里插入图片描述

根据冯·诺依曼结构,计算机分为五大部分,分别是:控制器、运算器、存储器、输入设备、输出设备。

输入设备(如鼠标键盘)和输出设备(如显示器)都属于外设(外部设备),而像硬盘、网卡这种既属于输入设备又属于输出设备。

从计算机的角度出发的话,操作系统将从输入设备读取到的数据写入到输出设备,这就是一次完整的 I/O 过程。

即 I/O 描述了计算机核心(CPU和内存)外部设备之间的数据转移的过程。

2、应用程序的视角

我们都知道,应用程序作为一个文件保存在磁盘中,只有加载到内存中成为一个进程才能够运行。

为了确保操作系统的安全性和稳定性,操作系统会将内存分为 内核空间用户空间,进行内存隔离。

而我们运行的应用程序都是运行在用户空间的,只有内核空间才能进行系统态级别的资源有关的操作,比如文件管理、进程通信、内存管理等。也就是说,我们想要进行 I/O 操作,就必须依赖内核空间的能力。但是,用户空间的程序是无法直接访问内核空间的。

这时我们就需要通过发起系统调用请求操作系统帮忙完成,所以应用程序想要执行 I/O 操作的话,必须通过调用内核提供的 系统调用 进行间接访问。

我们在平常开发过程中接触最多的就是 **磁盘 I/O(读写文件)**和 网络 I/O(网络请求和响应)

从应用程序的角度出发的话,我们的应用程序对操作系统的内核发起 I/O 调用(系统调用),操作系统负责的内核执行具体的 I/O 操作。即强调的是通过向内核发起系统调用完成对 I/O 的间接访问。

上述过程换句话说即一次 I/O 操作实际上包含两个阶段:

  • I/O 调用阶段:应用程序进程向内核发起系统调用
  • I/O 执行阶段:内核执行 I/O 操作并返回
    • 内核等待 I/O 设备准备好数据
    • 内核将数据从内核空间拷贝到用户空间

在这里插入图片描述

二、Java 中3种常见的 I/O 模型

  • 同步 I/O,是指用户空间线程是主动发起 I/O 请求的一方,内核空间是被动接受方。
  • 异步 I/O,则反过来,是指内核是主动发起 I/O 请求的一方,用户线程是被动接受方
  • 阻塞 I/O,阻塞是指用户空间程序的执行状态,用户空间程序需等到 I/O 操作彻底完成。传统的 I/O 模型都是同步阻塞 I/O。在 Java 中,默认创建的socket都是阻塞的。
  • 非阻塞 I/O,是指用户程序不需要等待内核IO操作完成后,内核立即返回给用户一个状态值,用户空间无需等到内核的 I/O 操作彻底完成,可以立即返回用户空间,执行用户的操作,处于非阻塞的状态。

1、同步阻塞 I/O(BIO)

应用程序中进程在发起 I/O 调用后至内核执行 I/O 操作返回结果之前,若发起系统调用的线程一直处于等待(阻塞)状态,则此次 I/O 操作为阻塞 I/O 。

阻塞 I/O 简称 BIO(Blocking IO)

在这里插入图片描述

如上图,同步阻塞 I/O 模型中,当用户线程发出 I/O 调用后,内核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,而此时用户线程也就会处于阻塞状态,用户线程交出 CPU 。当数据就绪之后,内核会将数据拷贝到用户空间,并返回结果给用户线程,用户线程才会接触阻塞状态。

  • BIO 的优点:

程序简单,在阻塞等待数据期间,用户线程挂起。用户线程基本不会占用 CPU 资源。

  • BIO 的缺点:

一般情况下,一个线程维护一个连接成功的 IO 流的读写。在并发量小时是没有问题的,但在并发很大时,BIO 是非常消耗系统资源的,这是行不通的。

2、同步非阻塞 I/O(NIO)

应用程序中进程在发起 I/O 调用后至内核执行 I/O 操作返回结果之前,若发起系统调用的线程不会等待而是立即返回,则此次 I/O 操作为非阻塞 I/O 模型。

非阻塞 I/O 简称 NIO(Non-Blocking IO)

在这里插入图片描述

如上图,同步非阻塞 I/O 模型中,当用户线程发起一个 read 操作后,并不需要等待,而是马上得到了一个结果。如果结果是一个调用失败的信息时,此时代表数据还没有准备好,他就可以再次发送 read 操作。一旦内核中的数据准备好了,并且又再次收到了用户线程的请求,那么他就马上将数据拷贝给了用户线程,然后返回。

在同步非阻塞 I/O 模型中,用户线程需要不断地询问内核数据是否就绪,也就是说同步非阻塞 I/O 模型不会交出 CPU ,而会一直占用 CPU。

即应用程序的线程需要不断的进行 I/O 系统调用,轮询数据是否已经准备好,如果没有准备好,直到完成系统调用为止。

  • NIO的优点:

每次发起的 IO 系统调用,在内核的等待数据过程中可以立即返回。用户线程不会阻塞,实时性较好。

  • NIO的缺点:

需要不断的重复发起 IO 系统调用,这种不断的轮询,将会不断地询问内核,这将占用大量的 CPU 时间,系统资源利用率较低。

★ I/O 多路复用模型

I/O 多路复用模型是目前使用得比较多的模型。Java 中的 NIO 可以看作是 I/O 多路复用模型(IO Multiplexing),而 Java 中的 NIO 可以通过的 Selector(选择器)达到一个线程管理多个客户端连接的效果。

IO 多路复用模型中,线程首先发起 select 调用,询问内核数据是否准备就绪,等内核把数据准备好了,用户线程再发起 read 调用。read 调用的过程(数据从内核空间 -> 用户空间)还是阻塞的。即在 read 调用之前会有一个 select 调用

在这里插入图片描述

IO 多路复用模型,通过减少无效的系统调用,减少了对 CPU 资源的消耗。

目前支持 IO 多路复用的系统调用,有 select,epoll 等等。select 系统调用,目前几乎在所有的操作系统上都有支持。

  • select 调用 :内核提供的系统调用,它支持一次查询多个系统调用的可用状态。几乎所有的操作系统都支持。
  • epoll 调用 :linux 2.6 内核,属于 select 调用的增强版本,优化了 IO 的执行效率。

3、异步非阻塞 I/O(AIO)

应用程序中在发起 I/O 调用后,用户进程立即返回,内核等待数据准备完成,然后将数据拷贝到用户进程缓冲区,最后发送信号告诉用户进程 I/O 操作执行完毕,则此次操作为异步 I/O。

异步 I/O 简称 AIO(Asynchronous I/O)

在这里插入图片描述

异步 I/O 真正实现了 I/O 全流程的非阻塞。用户线程完全不需要关心实际的整个 I/O 操作是如何进行的,只需要先发起一个请求,当接收内核返回的成功信号时表示 I/O 操作已经完成,可以直接去使用数据了。

相关内容

热门资讯

【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...