返回

北京老男孩教育

Java NIO核心组件学习笔记分享

java学习网更新时间:2023-01-15 浏览:156

Java NIO核心组件学习笔记分享

背景知识
同步、异步、阻塞、非阻塞
首先,这几个概念非常容易搞混淆,但NIO中又有涉及,所以总结一下[1]。
同步:API调用返回时调用者就知道操作的结果如何了(实际读取/写入了多少字节)。
异步:相对于同步,API调用返回时调用者不知道操作的结果,后面才会回调通知结果。
阻塞:当无数据可读,或者不能写入所有数据时,挂起当前线程等待。
非阻塞:读取时,可以读多少数据就读多少然后返回,写入时,可以写入多少数据就写入多少然后返回。
对于I/O操作,根据Oracle官网的文档,同步异步的划分标准是“调用者是否需要等待I/O操作完成”,这个“等待I/O操作完成”的意思不是指一定要读取到数据或者说写入所有数据,而是指真正进行I/O操作时,比如数据在TCP/IP协议栈缓冲区和JVM缓冲区之间传输的这段时间,调用者是否要等待。
所以,我们常用的 read() 和 write() 方法都是同步I/O,同步I/O又分为阻塞和非阻塞两种模式,如果是非阻塞模式,检测到无数据可读时,直接就返回了,并没有真正执行I/O操作。
总结就是,Java中实际上只有 同步阻塞I/O、同步非阻塞I/O 与 异步I/O 三种机制,我们下文所说的是前两种,JDK 1.7才开始引入异步 I/O,那称之为NIO.2。
传统IO
我们知道,一个新技术的出现总是伴随着改进和提升,Java NIO的出现亦如此。
传统 I/O 是阻塞式I/O,主要问题是系统资源的浪费。比如我们为了读取一个TCP连接的数据,调用 InputStream 的 read() 方法,这会使当前线程被挂起,直到有数据到达才被唤醒,那该线程在数据到达这段时间内,占用着内存资源(存储线程栈)却无所作为,也就是俗话说的占着茅坑不拉屎,为了读取其他连接的数据,我们不得不启动另外的线程。在并发连接数量不多的时候,这可能没什么问题,然而当连接数量达到一定规模,内存资源会被大量线程消耗殆尽。另一方面,线程切换需要更改处理器的状态,比如程序计数器、寄存器的值,因此非常频繁的在大量线程之间切换,同样是一种资源浪费。
随着技术的发展,现代操作系统提供了新的I/O机制,可以避免这种资源浪费。基于此,诞生了Java NIO,NIO的代表性特征就是非阻塞I/O。紧接着我们发现,简单的使用非阻塞I/O并不能解决问题,因为在非阻塞模式下,read()方法在没有读取到数据时就会立即返回,不知道数据何时到达的我们,只能不停的调用read()方法进行重试,这显然太浪费CPU资源了,从下文可以知道,Selector组件正是为解决此问题而生。
Java NIO 核心组件
1.Channel
概念
Java NIO中的所有I/O操作都基于Channel对象,就像流操作都要基于Stream对象一样,因此很有必要先了解Channel是什么。以下内容摘自JDK 1.8的文档
从上述内容可知,一个Channel(通道)代表和某一实体的连接,这个实体可以是文件、网络套接字等。也就是说,通道是Java NIO提供的一座桥梁,用于我们的程序和操作系统底层I/O服务进行交互。
通道是一种很基本很抽象的描述,和不同的I/O服务交互,执行不同的I/O操作,实现不一样,因此具体的有FileChannel、SocketChannel等。
通道使用起来跟Stream比较像,可以读取数据到Buffer中,也可以把Buffer中的数据写入通道。

当然,也有区别,主要体现在如下两点:
一个通道,既可以读又可以写,而一个Stream是单向的(所以分 InputStream 和 OutputStream)
通道有非阻塞I/O模式
实现
Java NIO中常用的通道实现是如下几个,可以看出跟传统的 I/O 操作类是一一对应的。
FileChannel:读写文件
DatagramChannel: UDP协议网络通信
SocketChannel:TCP协议网络通信
ServerSocketChannel:监听TCP连接
2.Buffer
NIO中所使用的缓冲区不是一个简单的byte数组,而是封装过的Buffer类,通过它提供的API,我们可以灵活的操纵数据,下面细细道来。
与Java基本类型相对应,NIO提供了多种 Buffer 类型,如ByteBuffer、CharBuffer、IntBuffer等,区别就是读写缓冲区时的单位长度不一样(以对应类型的变量为单位进行读写)。
Buffer中有3个很重要的变量,它们是理解Buffer工作机制的关键,分别是
capacity (总容量)
position (指针当前位置)
limit (读/写边界位置)
Buffer的工作方式跟C语言里的字符数组非常的像,类比一下,capacity就是数组的总长度,position就是我们读/写字符的下标变量,limit就是结束符的位置。Buffer初始时3个变量的情况

相关资讯

c++ vector 使用效率问题
2021-07-15 370
1. vector中的erase方式 高效率是很低。由于为了更好地维持vector中原素在存储空间中的持续性,在删掉某一原素以后,*将之后...
java技术有哪些优点优势
2021-07-15 348
Java技术性有以下优势:简易、面向对象编程、分布式系统、表述实行、鲁棒性、安全性、系统架构保持中立、生命期、性能卓越、线程同步及其动态...
Java未来发展的趋势
2021-06-15 341
没有Java,甚至不会有大数据的大发展,Hadoop本身就是用Java编写的。当你需要在运行MapReduce的服务器集群上发布新功能时,你需...
初学者适合学习哪些编程语言
2021-07-15 336
许多同学想改行程序编写,可是那么多的计算机语言究竟该怎么选呢?头痛~如果你是一名具备创新性的开发人员或是想变成一名具备展望工作能力的开发人员得话,那麼,你应该最少在**是的计算机语言中挑选一个,相近 Python, JavaScript, C#, C++, PHP, Java, 或是 go...
云计算技术与应用学什么东西
2021-07-16 330
云计算技术与应用是学什么的?众所周知,云计算技术是当前的热门技术, 云计算专*技*人才是香饽饽,计划学习云计算技术与应用...
学Java可以做哪些职位
2021-06-11 297
Java是时下非常流行的语言,这意味着有很多很多不同的工作可供选择。Java软件工程师入行1-3年,*已达到10-15万,而且在IT行业...
学什么技术有前途 Java怎么样
2021-07-19 292
如今正是互联网信息时代,随着时代的变迁肯定会发展的越来越好,而Java编程语言是最于我们生活息息相关的,用处范围广泛,比如:...
北京达内教学怎么样 北京达内教育学习环境好吗
2021-07-15 269
日给大伙儿分享一些有关达内教育学习中心的相片,了解一下达内教育学习中心自然环境怎样。下边就跟随我一起来吧...

相关课程

栏目导航