关于java的NIO(一)

关于java的NIO(一)

当面试官问到我:请解释一下java的NIO的时候,我真的是一脸懵逼,用了java这么久,真的是第一次听到这个词,所以本篇内容来讲解一下java的NIO(这篇全是理论文字

本文内容
  1. 什么是NIO
  2. NIO与IO的区别
  3. 通道和缓冲区
  4. 选择器
什么是NIO

先来一段官方的解释:

新的输入/输出 (NIO) 库是在 JDK 1.4 中引入的。NIO 弥补了原来的 I/O 的不足,它在标准 Java 代码中提供了高速的、面向块的 I/O。通过定义包含数据的类,以及通过以块的形式处理这些数据,NIO 不用使用本机代码就可以利用低级优化,这是原来的 I/O 包所无法做到的。

很明显,NIO和IO的作用都是一样的,是用来处理输入输出的,就是处理的方式不同,而且NIO比IO更强大,更快

NIO与IO的区别

在了解NIO与IO的区别之前,我们需要了解几个概念,通道(Channel),缓冲区(Buffer),选择器(Selector),这三个是NIO的核心,我们对比IO来讲

我们平常用的IO实际上叫作BIO(NIO和BIO都是同步的,还有一个异步的AIO,感兴趣的自己查一下),是我们最常用的操作之一,我们都知道,BIO操作是通过流来实现,输入流,输出流,就和水流一样,数据是一个字节一个字节的“流”过来的。这样做有什么优点,方便,来一个接一个就行了,但是缺点就是,得按顺序读取,不能前后移动,只能等前面的数据都走完之后,才能拿到后面的数据,如果需要前后移动的话,就需要用缓冲区保存全部的数据,NIO就利用了缓冲区解决了这个问题,数据都被读取到缓冲区,需要的时候就在缓冲区里面前后移动,随便拿

BIO还有个特点是阻塞,当线程需要IO操作的时候,会进入阻塞状态,直到IO操作结束,而NIO是非阻塞的,当线程需要IO操作的时候,会通过通道发送读取请求,如果没有可以返回的数据的时候,什么都不会获取,线程不会进入阻塞状态,而是还可以做其他的事,直到有需要的数据返回,在这个过程中,线程会不断的尝试读取数据,举个例子来解释,你去餐厅吃饭,饭还没做好的时候,你就干坐着等着,一直等到饭做好,再去做别的事,这个就是BIO的操作;第二天你再去吃饭,饭还没做好的时候,你出去买了包烟,然后回来看一下饭好了没,没好的话你再出去抽个烟,再来看看饭好了没,直到饭好了,你继续做别的事,这个就是NIO的操作

NIO还有一个BIO没有的东西,选择器,这里就要引入一个新的概念:IO多路复用,在服务端和客户端的场景中,一般是多个客户端去向一个服务端进行通信,也就是我们说的高并发,当我被问到怎么处理socket的高并发的情况的时候,我的第一反应是,使用多线程,OK,多线程在一定程度上是可以处理高并发的,但是要知道,一旦线程多了,对于资源的竞争也是相当激烈,这就会让系统变慢,而且一台服务器并不是可以无限制的创建线程,所以就需要IO多路复用,举例子来说明

当你要拿快递的时候,你需要等快递员把快递送到你手上,这就是一个IO的操作,现在你的学校的所有人都要拿快递,这个时候就有多个IO操作,多个不同的快递员都需要往你的学校送快递,这就是一个高并发的IO场景,这个时候学校为了方便学生,在学校里面设立了一个快递点,所有的快递员只要把快递送到快递点,然后快递点通知你快递到了

在这个例子里面,把学校看做服务器、快递看做客户端,学校就是通过快递点实现了IO多路复用,而在NIO里面,就是使用选择器,来监听多个通道,实现IO多路复用

通道和缓冲区
  • 通道

在BIO中,数据通过流进行传递,而在NIO中,数据通过通道(Channel)进行传递,通道就是对流的模拟,他的作用除了读取和写入数据,主要是实现非阻塞式读写(这个在下篇博客介绍),使用通道,可以用最小的总开销来访问操作系统本身的 I/O 服务,而缓冲区则是通道发送和接收数据的端点

通道还有一个新功能Scatter/Gather,翻译过来就是分散/收集,也叫作本地矢量IO
,上面不是说了缓冲区是通道发送和接收数据的端点,所以这个新功能的作用就是在读取数据的时候,把数据按顺序分散到多个缓冲区(缓冲区就是一个数组),直到通道中的数据读取完,或者缓冲区装满;而在写数据的时候,就会把多个缓冲区的数据按顺序收集,然后发送数据。这个功能的最大优点就是减少或避免了缓冲区的拷贝和系统的调用,相比BIO提高了性能

  • 缓冲区

缓冲区有四个属性:

  1. 容量(Capacity) :就是缓冲区能保存的数据的最大容量,在创建时被设定,并且后面不能改变
  2. 上界(Limit):就是缓冲区里的数据量,代表缓冲区里面有多少数据
  3. 位置(Position): 就是下一个要操作的数据的位置,前面介绍的可以在缓冲区前后移动 ,就是通过这个属性
  4. 标记(Mark):就是上一次读写的位置,和Position刚好对立

这四个属性里面,1,3,4都很容易理解,这里讲一下Limit上界,当写入数据的时候,他代表的就是所能写入的最大条数,当读取数据的时候,他代表的就是当前保存的数据的条数,所以他的作用就是,进行缓冲区的读写操作,放一个图
在这里插入图片描述
在我们原本的BIO中,我们对数据的操作都是直接写入流,或者直接从流读取,而在NIO中,我们并不能直接对通道进行操作,在写入操作的时候我们只能将数据写入缓冲区,在读取操作的时候,我们只能从缓冲区读取数据,而缓冲区的数据是怎么进入通道和从通道中读取,这就是上面介绍的通道的Scatter/Gather,这也解释了为什么说缓冲区是通道发送和接收数据的端点

选择器

选择器可以说是NIO最核心的东西,它主要解决的就是上面说的高并发问题,通过监听一个到多个NIO通道,一旦有通道有数据传递,那么就会触发选择器的事件,从而进行处理,也就是用一个线程,管理多个通道,用于网络的话,就是管理多个网络连接,放个图
在这里插入图片描述
这个选择器更多是用在网络NIO里面,对于普通的文件操作用的比较少

到这里为止,关于NIO的基础概念就算讲完了,相信对NIO是什么,NIO有什么特点,NIO和IO的区别心中应该有个数了,而NIO的非阻塞主要是体现在网络上,非阻塞的通道都是用于网络编程,所以下篇博客,我来介绍普通的NIO和网络NIO

NIO官方网址:https://www.ibm.com/developerworks/cn/education/java/j-nio/j-nio.html

下篇博客地址:https://blog.csdn.net/Dongroot/article/details/88794825

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值