Java IO模型详解

news2024/12/31 6:07:03

文章目录

    • 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 操作已经完成,可以直接去使用数据了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/333775.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Flutter 小技巧之 3.7 更灵活的编译变量支持

今天我们聊个简单的知识点,在 Flutter 3.7 的 release-notes 里,有一个没有出现在 announcement 说明上的 change log ,可能对于 Flutter 团队来说这个功能并不是特别重要,但是对于我个人而言,这是一个十分重要的能力补…

什么是模板方法模式?

在面向对象程序设计过程中,程序员常常会遇到这种情况:设计一个系统时知道了算法所需的关键步骤,而且确定了这些步骤的执行顺序,但某些步骤的具体实现还未知,或者说某些步骤的实现与具体的环境相关。例如,去…

阿里云国际服务器ECS特性与优势

阿里云国际服务器的 ECS 作为一种安全、可靠、灵活、可扩展的云计算服务,不仅可以减少运行和维护,而且可以提高运行和维护效率,使用户关注核心业务的创新。 阿里云国际服务器ECS优势一:产品丰富 阿里云国际云服务器 ECS 可以提供…

《MySql学习》 SQL 语句的更新过程

《MySql学习》 SQL 语句的更新过程 一.SQL查询语句的执行过程 上一篇博文记录了SQL查询语句的执行过程,首先客户端通过TCP三次握手与Server层的连接器建立连接(短连接与长链接),缓存权限。然后去查询缓存(8.0后移除&…

联想服务器双品牌的思考:融合化、场景化、订阅化、绿色化,打造全栈新算力基础设施

联想集团执行副总裁兼中国区总裁刘军:智能化转型是中国企业未来十年穿越经济周期的利器,智能化生产力水平决定了企业发展的速度与高度。 联想创新性提出融合化、场景化、订阅化及绿色化的“四维算力”,致力于成为中国领先的智能IT基础设施提供…

微服务--Feign学习

Feign远程调用: RestTemplate发起远程调用的代码: 存在下面的问题 代码可读性差,编程体验不统一参数复杂URL难以维护 Feign的介绍:Feign是一个声明式的http客户端,官方地址:https://github.com/OpenFeign/…

论文文献引用规范和标准(国标GBT7714)@endnote国标样式

文章目录论文文献引用规范和标准(国标GBT7714)国标GBT7714-2015endnote stylerefs简述国标GBT7714条目的组织格式Noteword中的文献交叉引用超链接文献引用示例endNote资源和基本使用endnote或其他文献引用工具下载word中的其他引文技巧知网国标格式引文引…

谈谈Java Optional的坑

开端: 大家好,我是老白。昨天朋友提出的java8后出来的自带的对象判定方式Optional.ofNullable(),后来查询了一些资料和自己试验了一些demo资料,在这里记录分享个大家 作用:判断对象是否为空,是则重新创建一个新对象&…

ABAP 搜索帮助带出多个字段描述 更新屏幕字段

文章目录需求解析1-DYNP_GET_STEPL2-F4IF_INT_TABLE_VALUE_REQUEST3-获取返回值4-把相应字段更新到内表5-DYNP_VALUES_UPDATE代码需求 如图,当我点击责任工序的搜说帮助时, 同时会把责任人员的描述带出来. 解析 1-DYNP_GET_STEPL 这个方法就是获取当前的循环步骤 2-F4IF_I…

浏览器中的 JavaScript 执行机制

思维导图 本文为反复学习极客时间-《浏览器的工作原理与实践》-浏览器中的 JavaScript 执行机制章节中的一些思考与记录。 一些重要概念 变量提升 所谓的变量提升,是指在 JavaScript 代码执行过程中,JavaScript 引擎把变量的声明部分和函数的声明部分…

你可能还不知道的 console.log 替代品

通过使用 javascript 对象的破坏能力,您可以这样做:const{ log } console; log("hi"); log("testing");你可以将log函数更改为您想要的任何其他名称,如下所示:const{log: myLog } console; myLog("hi&qu…

vue插槽 Slots

一、插槽是什么&#xff1f; 插槽就是子组件中的提供给父组件使用的一个占位符&#xff0c;用<slot></slot> 表示, 父组件可以在这个占位符中填充任何模板代码&#xff0c;如 HTML、组件等&#xff0c;填充的内容会替换子组件的<slot></slot>标签。 简…

OpenSergo Spring Cloud Alibaba 带来的服务治理能力

作者&#xff1a;十眠、牧思 Spring Cloud 应用为何需要服务治理 随着微服务技术的发展&#xff0c;微服务(MicroServices) 的概念早已深入人心&#xff0c;越来越多的公司开始使用微服务架构来开发业务应用。 如果采用得当&#xff0c;微服务架构可以带来非常大的优势。微服…

IDEA与eclipse桌面配置基础(笔记)

在eclipse中配置jdk Window–>Preferences–>java–>installed JREs–>add–>Standard VM–>选择jdk安装路径就好了 设置字符集编码为utf-8&#xff0c;防止中文乱码 设置字符集编码为UTF-8&#xff1a;Window–>Preferences–>General–>Workspace…

第四次工业革命新十年:看跨越智能化鸿沟的联想范式

十年前&#xff0c;GE推出全球第一个工业互联网平台Predix&#xff1b;同年&#xff0c;在2013汉诺威工业博览会上&#xff0c;德国正式推出工业4.0概念。由此&#xff0c;全球开启了以工业4.0和工业互联网为核心的第四次工业革命浪潮&#xff0c;智能技术成为了第四次工业革命…

4N25光耦合器:简单的应用电路

4N25光耦合器&#xff1a;简单的应用电路 介绍 4N25是一款6引脚光电晶体管耦合器。本文根据其传动特性介绍了 4N25 的非线性和线性应用。 4N25概述 光电耦合器4N25的内部电路结构如图1所示。 图1.4N25内部电路结构 该芯片为双列直插式器件&#xff0c;外引线为6根&#xff0…

Dart语法学习-基础-类

Classes Using constructors 使用构造函数创建对象。 构造函数名称可以是 ClassName 或 ClassName.identifier。 例如&#xff0c;以下代码使用 Point() 和 Point.fromJson() 构造函数创建 Point 对象&#xff1a; class Point {var x;var y;Point(int this.x, int this.y);…

Java --- Integer.parseInt()

parseInt() 方法是java.lang 包下Integer 类的一个方法。 Java Integer parseInt() 方法共有三种不同类型&#xff0c;可以根据其参数进行区分。 用法: 以下是 parseInt() 方法的声明&#xff1a; public static int parseInt (String s) public static int parseInt (Strin…

捐赠物品管理系统-php mysql

目 录 第一章 引言 1 1.1研究背景 1 1.2研究现状 1 1.3 系统相关技术与环境简介 1 1.3.1 PHP 1 1.3.2 Apache 2 1.3.3 MySQL数据库 2 1.3.4 运行环境 Windows 3 1.3.5 appserv 3 1.3.6 Dreamweave8 3 1.3.7 EditPlus 4 第二章 需求分析…

前端必备开发编译器详解

一、前言 前端开发编译器有很多&#xff0c;例如&#xff1a;WebStorm、VS Code、HBuilder X、Sublime Text等等。在这里就不一一介绍了&#xff0c;这里主要讲解VS Code和HBuilder X 编译器。 二、VS Code Visual Studio Code (简称 VS Code) 是一款免费开源的现代化轻量级…