我的编程空间,编程开发者的网络收藏夹
学习永远不晚

一文让你了解透彻Java中的IO模型

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

一文让你了解透彻Java中的IO模型

什么是IO

IO(Input/Output),也就是输入和输出的简称,从计算机结构的角度来看,IO,就是输入数据到计算机中,计算机输出数据到计算机外,下面有一张十分经典的冯·诺伊曼结构图,将计算机分为五大部分:运算器、控制器、存储器、输入设置、输出设备。

输入设备向计算机输入数据,输出设备接收计算机输出的数据。

所以,从计算机结构的角度来看IO,IO就是描述了计算机系统和外部设备之间通信的过程

接下来我们再从应用程序的角度去了解一下IO:在操作系统中,为了保证操作系统的稳定性和安全性,一个进程的地址空间被划分为了用户空间(User space)和内核空间(Kernel space)

那么什么是用户空间,什么是内核空间呢?

  • 用户空间是普通应用程序可访问的内存区域。
  • 内核空间是操作系统内核访问的区域,独立于普通的应用程序,是受保护的内存空间。

可以简单的理解为我们平常运行的应用程序,都是运行在用户空间中的,它没有权限去进行一些系统态级别的资源相关操作,比如文件管理、内存管理、等等,这些操作都是要依赖内核空间才能完成,也就是说,我们如果想要进行IO操作,一定是要依赖内核空间的能力,并且这里需要注意一点:用户空间的程序不能直接访问内核空间

那么如果要发起一次IO操作,那应该怎么办呢?

当我们需要执行一次IO操作的时候,由于没有执行IO操作的权限,只能发起系统调用请求操作系统来帮忙完成,所以用户进程想要执行IO操作的话,必须通过系统调用来间接的访问内核空间,比如我们最常见的IO操作就是磁盘IO(读写文件)和网络IO(网络请求和响应)。

那么从应用程序的视角去看IO的话,我们的应用程序发起对操作系统的内核发起IO调用(系统调用,注意只是调用),操作系统去负责内核执行具体的IO操作。(如果这段话不是很好理解,可以理解为调包,比如别人写好了的工具类,我们不需要关注里面的实现细节,只需要调用它的方法就好了,这里我们的应用程序就是发起了一个调用,但是真正执行的还是我们的操作系统)

当应用程序发起IO调用之后,会经历下面两个步骤:(这里一定要记住这两点,它和后面息息相关!)

  • 内核等待IO设备准备好数据
  • 内核将数据从内核空间拷贝到用户空间

常见的IO模型

IO模型有很多种(比如在UNIX系统下,IO模型一共分为5种:同步阻塞IO、同步非阻塞IO、IO多路复用、信号驱动IO、异步IO),本篇文章只讲述Java中的IO模型,Java中的IO被分为三类:BIO、NIO、AIO

BIO(Blocking IO)

BIO属于同步阻塞IO模型,应用程序发起read调用之后,会一直阻塞,直到内核把数据从内核空间拷贝至用户空间。

BIO就是Java中最传统的IO模型,相关的类和接口都在java.io这个包下面,因为现在用的人很少(后面看它的特点就知道为什么了),所以我们这里简单介绍一下它的一些特点就好了。

  • 对高并发场景下对于线程资源的消耗较高,每一个连接需要使用一条线程单独处理。
  • 传输较小对象时存在频繁的线程上下文切换等性能问题。

如何优化

那么怎么去优化这个BIO呢?

首先上面说了BIO的缺点之一就是它是有多少连接就需要多少线程的模型,但是对于用户来说,打开一个连接,然后关闭一个连接是十分常见且频繁的事情,而与之对应的就是创建线程和销毁线程,但是创建线程和销毁线程对于操作系统来说是十分消耗资源的,所以想到的优化就是使用线程池去进行优化BIO。

NIO的面世

但是BIO的模型决定了它的上限,它始终是同步阻塞的IO模型,阻塞就会导致不能使用单线程处理多个请求,所以这个时候就需要修改它的模型,将调用read()、write()方法不再是阻塞的,这样就可以使用单线程处理多个请求,而这样就不再是同步阻塞的IO模型了,也就是我们下面要说到的NIO了。

NIO(Non-blocking/New IO)

Java的NIO是Java1.4引入的,对应的是java.nio包,提供了channel、selector、buffer等抽象。

Java中的NIO可以看作是IO多路复用模型,但是也有人认为它是同步非阻塞IO模型,这里我们先简单介绍一下这两种模型:

同步非阻塞IO模型

这个相比同步阻塞IO模型,同步非阻塞IO模型就是通过轮询的方式,避免了一直阻塞

但是从图中也能看出问题所在,就是应用程序不断的进行IO系统调用轮询数据是否已经准备就绪的这段时间,是十分消耗CPU资源的(说白话就是反复调用read操作)

所以这个时候就引入了IO多路复用模型。

IO多路复用模型

在IO多路复用模型中,线程首先发起select调用,询问内核数据是否准备就绪,等待内核把数据准备好了,会返回一个ready调用,告诉你,我准备好了,这个时候用户线程再发起read调用。注意:read调用的过程依然是阻塞的(数据从内核空间拷贝至用户空间这段时间)

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

Java中的NIO

Java中的NIO,有一个十分重要的概念,就是选择器(selector),也被称为多路复用器,通过它就可以实现使用一个线程管理多个客户端连接(这里是不是和BIO就不一样了,最大的优化的点就在这里) 。当客户端数据到了之后,线程再为客户端进行服务。

下面给出一张JavaNIO的图:

这张图就能很好的说明了NIO的特点了。

AIO(Asynchronous IO)

AIO,也被称为NIO 2.0,Java7中引入的异步IO模型,很多人都不理解非阻塞IO和异步IO到底有什么差别,其实异步IO就是基于事件和回调机制去实现的,也就是说用户调用操作之后会立马返回,不会阻塞,当后台处理完成,操作系统会通知相应的线程进行后续操作

目前来说AIO的应用还没有十分广泛,应用最多的是NIO。

总结

最后放一张图来总结Java中的IO模型:

到此这篇关于一文让你了解透彻Java中的IO模型的文章就介绍到这了,更多相关Java IO模型内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

一文让你了解透彻Java中的IO模型

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

一文让你了解透彻Java中的IO模型

本文只是说明了IO模型,让你了解IO模型是什么,怎么区分IO模型,以及分析了Java中的三种IO模型,本文是纯理论知识,看完之后会让你对IO有更加深刻的理解,感兴趣的同学可以参考一下
2023-05-18

一文带你你搞懂Java的3种IO模型

在Java中,一共有三种IO模型,分别是阻塞IO(BIO)、非阻塞IO(NIO)和异步IO(AIO),本文将给大家详解的介绍这三种IO模型,文中有相关的代码示例,需要的朋友可以参考下
2023-05-19

一文彻底了解Java的组合模式

组合模式(Composite Pattern)指将对象组合成树形结构以表示“部分-整体”的层次结构, 使得用户对单个对象和组合对象的使用具有一致性。本文就来带大家深入了解一下Java的组合模式吧
2023-02-24

一文带你了解java中的泛型、反射与注解

一文带你了解java中的泛型、反射与注解?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。泛型擦除泛型擦除: 泛型只在编译时期有效,编译后的字节码文件中不存在泛型信息。声明泛型
2023-05-31

一文带你了解Node.js中的http模块

本篇文章给大家了解一下Node.js http模块,介绍一下使用http模块创建服务器的方法,希望对大家有所帮助!
2023-05-14

一文带你了解Node.js中的path模块

Node.js和Python技术类似, 都致力于能够实现跨平台的通用代码。 为此,针对路径的拼接, Node.js提供了path模块,本文就来讲讲path模块的使用
2023-03-21

一文带你了解Java中的SPI机制

SPI全称是ServiceProviderInterface,是一种JDK内置的动态加载实现扩展点的机制,本文主要为大家介绍了SPI机制的原理与使用,需要的可以参考一下
2023-05-15

一文带你了解node中的的模块系统

本篇文章带大家进行node学习,深入浅出的了解node中的的模块系统,希望对大家有所帮助!
2023-05-14

一文带你深入了解JavaScript中的原型&原型链

相信不少同学在面试的时候经常在基础上就挂掉了,当下行情实属严峻,如果我们基础都没有打牢固的话,实属有点面试浪费机会。本文就来和大家聊聊JavaScript中的原型&原型链,希望对大家有所帮助
2023-02-13

一文带你了解Java中基本数据类型的包装类

这篇文章将为大家详细讲解有关一文带你了解Java中基本数据类型的包装类,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Java是面向对象的编程语言,包装类的出现更好的体现这一思想。 其次,包装
2023-05-31

一文带你深入了解C++中的类型转换

在C语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与接收返回值类型不一致时,就需要发生类型转化。本文主要介绍了C++中常见的四个类型转换,需要的可以参考一下
2022-12-27

一文带你了解Java中的函数式编程

函数式编程的理论基础是阿隆佐·丘奇(AlonzoChurch)于1930年代提出的λ演算(LambdaCalculus)。这篇文章主要为大家介绍了函数式编程的相关知识,希望对大家有所帮助
2023-05-14

一文带你了解Golang中类型转换库cast的使用

你是否在使用Go的过程中因为类型转换的繁琐而苦恼过?你是否觉得Go语言中的类型断言可能会panic而对自己写的代码有那么一点点不放心?本文就为大家推荐一个用于类型转换的第三方库cast绝对是一个值得尝试的选择
2023-02-08

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录