如何理解NIO

文章目录

    • 1.什么是NIO?
    • 2.为什么用NIO,传统IO有什么缺陷?
    • 3.NIO和IO的区别
    • 4.怎么理解NIO是面向块的、非阻塞的
    • 5.NIO是怎么实现的?

1.什么是NIO?

java.nio全称java non-blocking IO(实际上是 new io),是指JDK 1.4 及以上版本里提供的新api(New IO) ,为所有的原始类型(boolean类型除外)提供缓存支持的数据容器,使用它可以提供非阻塞式的高伸缩性网络。

2.为什么用NIO,传统IO有什么缺陷?

一个使用传统阻塞I/O的系统,如果还是使用传统的一个请求对应一个线程这种模式,一旦有高并发的大量请求,就会有如下问题:

1、线程不够用, 就算使用了线程池复用线程也无济于事;
2、阻塞I/O模式下,会有大量的线程被阻塞,一直在等待数据,这个时候的线程被挂起,只能干等,CPU利用率很低,换句话说,系统的吞吐量差;
3、如果网络I/O堵塞或者有网络抖动或者网络故障等,线程的阻塞时间可能很长。整个系统也变的不可靠

最直接的体现在于服务器与客户端进行通讯时,每加入一台客户端需要一个IO线程阻塞等待对方数据传送,会导致服务器不断开启线程,但这些线程大部分时间都是阻塞在那里,浪费资源,并且支持不了大并发。

3.NIO和IO的区别

原有的 IO 是面向流的、阻塞的,NIO 则是面向块的、非阻塞的

原始的IO是面向流的,不存在缓存的概念。Java IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方。此外,它不能前后移动流中的数据。如果需要前后移动从流中读取的数据,需要先将它缓存到一个缓冲区
Java IO的各种流是阻塞的,这意味着当一个线程调用read或 write方法时,该线程被阻塞,直到有一些数据被读取,或数据完全写入,该线程在此期间不能再干任何事情了。

4.怎么理解NIO是面向块的、非阻塞的

NIO是面向缓冲区的。数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动,这就增加了处理过程中的灵活性。
Java NIO的非阻塞模式,使一个线程从某通道发送请求读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取,而不是保持线程阻塞,所以直至数据变的可以读取之前,该线程可以继续做其他的事情。 非阻塞写也是如此,一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。
通俗理解:NIO是可以做到用一个线程来处理多个操作的。假设有10000个请求过来,根据实际情况,可以分配50或者100个线程来处理。不像之前的阻塞IO那样,非得分配10000个。

5.NIO是怎么实现的?

1.buffer 缓存数组

缓冲区本质上是一个可以写入数据的内存块,然后可以再次读取,该对象提供了一组方法,可以更轻松地使用内存块,使用缓冲区读取和写入数据通常遵循以下四个步骤:

  1. 写数据到缓冲区;
  2. 调用buffer.flip()方法;
  3. 从缓冲区中读取数据;
  4. 调用buffer.clear()或buffer.compat()方法;

当向buffer写入数据时,buffer会记录下写了多少数据,一旦要读取数据,需要通过flip()方法将Buffer从写模式切换到读模式,在读模式下可以读取之前写入到buffer的所有数据,一旦读完了所有的数据,就需要清空缓冲区,让它可以再次被写入。

三个重要概念(参数)

a.容量(capacity)

b.界限(limit)

c.位置(position)

在这里插入图片描述
缓冲区常用的操作
向缓冲区写数据:

  1. 从Channel写到Buffer;
  2. 通过Buffer的put方法写到Buffer中;
    从缓冲区读取数据:
  3. 从Buffer中读取数据到Channel;
  4. 通过Buffer的get方法从Buffer中读取数据;
    flip方法:
    将Buffer从写模式切换到读模式,将position值重置为0,limit的值设置为之前position的值;
    clear方法 vs compact方法:
    clear方法清空缓冲区;compact方法只会清空已读取的数据,而还未读取的数据继续保存在Buffer中;

2.channel

a. 通道可以同时进行读写,而流只能读或者只能写

b. 通道可以实现异步读写数据

c. 通道可以从缓冲读数据,也可以写数据到缓冲:

channel提供了一个map()方法,可以直接将数据映射到内存中。
在这里插入图片描述

3.Selector(选择器)

可以检测多个NIO channel,看看读或者写事件是否就绪。

多个Channel以事件的方式可以注册到同一个Selector,从而达到用一个线程处理多个请求成为可能。

在这里插入图片描述

selector的创建

通过调用Selector.open()方法创建一个Selector对象

注册Channel到Selector

channel.configureBlocking(false);

channel.register(selector, Selectionkey.OP_READ);

注:Channel必须是非阻塞的。

所以FileChannel不适用Selector,因为FileChannel不能切换为非阻塞模式,更准确的来说是因为FileChannel没有继承SelectableChannel。Socket channel可以正常使用。

register() 方法的第二个参数。这是一个“ interest集合 ”,意思是在通过Selector监听Channel时对什么事件感兴趣。可以监听四种不同类型的事件:

  • Connect
  • Accept
  • Read
  • Write

SelectionKey介绍
一个SelectionKey键表示了一个特定的通道对象和一个特定的选择器对象之间的注册关系。
key.attachment(); //返回SelectionKey的attachment,attachment可以在注册channel的时候指定。
key.channel(); // 返回该SelectionKey对应的channel。
key.selector(); // 返回该SelectionKey对应的Selector。
key.interestOps(); //返回代表需要Selector监控的IO操作的bit mask
key.readyOps(); // 返回一个bit mask,代表在相应channel上可以进行的IO操作。

理解

传统IO在读写过程中是不允许停止的需要一直占用线程,对于一个一直有内容可读的文件不用切换线程这样效率的确不错,但是对于网络通讯中网络传输的并发需要不停开启新的线程并且对于计算机而言,它的大部分时间都是阻塞的,所以对于这种情况我们就对它进行了改写使用NIO非阻塞式的IO。

非阻塞式的IO,将内容写到一个Buffer中通过操作Bufer的标识(或者说游标),来改变其读或者写的状态,将它变成了分块的模式,通过通道channel进行数据传递,对内存中内容进行映射,读完了就结束,不需要一直占用线程。然而对于channel要有标识需要知道每个channel对应的谁写的谁读的问题,于是就有了Selector,通过regiser注册每个channel这样就可以知道哪个channel读好了,写完了的过程,执行其他的操作,每个channel不是单独的占用线程.这样就更好的支持了并发。

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

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

相关文章

sublime php快捷键,分享Sublime Text 3快捷键精华版!

下面由sublime教程栏目给大家介绍Sublime Text 3 快捷键精华版,希望对需要的朋友有所帮助!CtrlShiftP:打开命令面板CtrlP:搜索项目中的文件CtrlG:跳转到第几行CtrlW:关闭当前打开文件CtrlShiftW&#xff1a…

JDBC中使用preparedStatement防止SQL注入

一、SQL注入 SQL注入是一种比较常见的网路攻击方式,一些恶意人员在需要用户输入的地方,恶意输入SQL语句的片段,通过SQL语句,实现无账号登录,甚至篡改数据库。 二、SQL注入实例 登录场景: 在一个登录界面…

Java预科篇1-学前

Java预科篇1-学前 1、markdown语法 Markdown是一种纯文本格式的标记语言。通过简单的标记语法,它可以使普通文本内容具有一定的格式。 优点: 因为是纯文本,所以只要支持Markdown的地方都能获得一样的编辑效果,可以让作者摆脱排…

Java预科篇2-环境搭建

Java预科篇2-环境搭建 1、Java历史 1995年 Java问世1996年 Java 1.01999年 Java 1.2发布(JAVA SE\JAVA EE\JAVA ME)… … …2004年 Tiger 发布(JAVA5.0),Java 登录火星2011年 7月由Oracle正式发布Java7.02014年 3月19日,Oracle公…

php中如何配置环境变量,如何配置phpstorm环境变量如何配置phpstorm环境变量

大话西游6664版。根据你的系统平台下载相应的版本后,如果是压缩文件,先解压后双击运行,不是压缩文件,直接双击运行就可以了,运行后出现下面的界面,在下面界面上单击“Next”。跟所有的软件安装包一样&#…

Java基础篇1——变量与数据类型

Java基础篇1——变量与数据类型 1、标识符命名规则 标识符以由大小写字母、数字、下划线(_)和美元符号($)组成,但是不能以数字开头。大小写敏感不能与Java语言的关键字重名不能和Java类库的类名重名不能有空格、、#、、-、/ 等符号长度无限制应该使用有意义的名称…

Error running tomcat8 Address localhost:1099 is already in use 错误解决

错误情况: 在IDEA上运行web项目时报错:Error running (项目名) Address localhost:1099 is already in use 解决方法: 第一步:打开Windows运行,如下图 第二步:按下回车或点击确定…

matlab数据处理 书,matlab数据处理记录

最近在看一篇论文,觉得文章的数据处理效果十分的惊艳!所以想着如何用matlab将类似的效果实现出来,但最近有一个任务,以后慢慢更新吧!先挖一个坑!1. 二维图形绘制二维坐标轴图像涉及的部分包含曲线的颜色、点…

MATLAB接收机位置解算,GPS-receiver GPS软件接收机代码 完整的捕获 解算定位 (可 8个通道) matlab 240万源代码下载- www.pudn.com...

文件名称: GPS-receiver下载 收藏√ [5 4 3 2 1 ]开发工具: matlab文件大小: 148 KB上传时间: 2015-07-02下载次数: 0提 供 者: 金亚强详细说明:GPS软件接收机代码 完整的捕获接受解算定位代码(可接受8个通道)-GPS software receiver codes文件列表(点击判断是…

oracle中$的用法,关于expdp 中query用法小结

今天看到群里有人问到关于在使用expdp导出数据中使用query参数报错的解决方法,自己也出于好奇心瞎折腾了一把,现记录如下1.第一次尝试的时候[oracleDB ~]$ expdp scott/scott tablesemp1 dumpfileemp1.dmp logfileemp1.log queryemp1:"where rownum…

oracle fnd file.log,OracleEBSWIP模块DebugLog收集方法

How to generate WIP debug log files in ONLINE cases? For 11.5.10 and above, the WIP debug log files will be created ifHow to generate WIP debug log files in ONLINE cases?For 11.5.10 and above, the WIP debug log files will be created if1. FND: Debug Log F…

linux怎么重装ssh服务器,Linux平台下安装SSH

什么是SSH?Secure Shell(缩写为SSH),由IETF的网络工作小组(Network Working Group)所制定;SSH为一项创建在应用层和传输层基础上的安全协议,为计算机上的Shell(壳层)提供安全的传输和使用环境。传统的网络服务程序,如r…

Java核心类库篇4——集合

Java核心类库篇4——集合 1、集合的意义 记录单个数据内容时,则声明一个变量记录多个类型相同的数据内容时,声明一个一维数组记录多个类型不同的数据内容时,则创建一个对象记录多个类型相同的对象数据时,创建一个对象数组记录多…

计划任务文件 linux,Linux之任务计划

一、单次任务计划二、周期性任务计划一、单次任务计划命令:batch:系统空闲时自动执行,不常用at:可以使用相对时间、绝对时间或模糊时间,例如相对时间:at now3min,表示3分钟后执行绝对时间&#…

Java核心类库篇8——网络编程

Java核心类库篇8——网络编程 1、七层网络模型 OSI(Open System Interconnect),即开放式系统互联,是ISO(国际标准化组织)组织在1985 年研究的网络互连模型。 当发送数据时,需要对发送的内容按…

linux同花顺乱码,打开同花顺软件全是问号

官方答案:字体库字体乱码【原因分析】:系统字体缺失,损坏。【解决方案】方案一:使用360电脑门诊进行修复1.打开【360安全卫士】—【电脑专家】搜索乱码,然后会弹出如下六个解决方案,根据当前计算机的故障现…

嵌入式linux组件,嵌入式Linux系统的几大组件!

原标题:嵌入式Linux系统的几大组件!本文概述了Linux系统的几大组件,描述了这些组件之间的关系。文章解释了术语,并描述看似很基础的细节。每个Linux系统都有许多主要组件。其中一个组件(引导加载程序)从技术上讲是Linux之外的&…

c语言字符串strchr,Strchr()C语言字符串处理功能

strchr()函数不如strcpy(),strcat(),strcmp(),strupr(),strlwr(),strlen()直观c strchr函数,因此需要代码理解:代码来自C语言开发入门和项目实战书:#include#includeint main(){字符字符串[50];char * str&…

Java数据库篇1——数据库配置

Java数据库篇1——数据库配置 1、数据库 数据库(DataBase) 就是存储和管理数据的仓库本质是一个文件系统, 还是以文件的方式,将数据保存在电脑上 2、数据库的优点 存储方式优点缺点内存速度快不能够永久保存,数据是临时状态的文件数据是可以永久保存的使用IO流操作文件, 不…

c语言里寄存器.1说明意思,C语言复习+寄存器地址名称映射

C语言复习寄存器地址名称映射一.参考资料探索者STM32F4开发板:**《STM32F4开发指南-库函数版本》4.1小节C语言基础知识复习4.6小节 MDK中寄存器地址名称映射**STM32F4xx官方资料:《STM32F4xx中文参考手册》-第7章通用IO二.C语言复习位操作GPIOA->ODR|…