标签:异步 消息中间件 管理 之间 spl java 特性 sock 流量
Java NIO
全称java non-blocking IO
,是指jdk1.4
及以上版本里提供的新api
(New IO
),为所有的原始类型(boolean
类型除外)提供缓存支持的数据容器,使用它可以提供非阻塞式的高伸缩性网络。
Java NIO
提供了与标准IO
不同的IO
工作方式,Channel
、Buffer
和Selector
构成了核心的API
。其它组件,如Pipe
和FileLock
,只不过是与三个核心组件共同使用的工具类。
Channel and Buffer
):标准的IO
基于字节流和字符流进行单向的数据读写操作。而NIO
是基于通道(Channel
)和缓冲区(Buffer
)进行操作,数据总是从通道中读取到缓冲区中,或者从缓冲区中写入到通道中。
Asynchronous IO
):Java NIO
可以让你异步的使用IO
,例如:当线程从通道读取数据到缓冲区时,线程还是可以进行其他事情;当数据被线程写入到缓冲区时,线程可以继续处理它。从缓冲区写入通道也类似。
Selector
):Java NIO
引入了选择器的概念,选择器用于监听多个通道的事件(比如:连接打开,数据读取和数据写入)。因此,单个的线程可以监听多个数据通道。
下面就来详细介绍Java NIO
的相关知识。
Java NIO
由以下几个核心部分组成:
基本上,所有的IO
在
NIO中都从一个
Channel`开始:
通道Channel
有点像流(Stream
),两者可以做个简单对比:
Channel
读到Buffer
中,也可以从Buffer
写到Channel
中。这里有个图示:
Channel和
Buffer`有好几种类型。
JAVA NIO
中的一些主要Channel
的实现,主要涵盖了文件IO
和UDP
、TCP
的网络IO
:
UDP
读写网络中的数据TCP
读写网络中的数据TCP
连接,像Web
服务器那样。对每一个新进来的连接都会创建一个SocketChannel
。JAVA NIO
中关键的Buffer
实现,涵盖了除boolean
的其余7
种基本数据类型(byte
、short
、int
、long
、float
、double
和 char
):
Selector
允许单线程处理多个Channel
的连接事件和数据读写。如果你的应用打开了多个连接(通道),但每个连接的流量都很低,使用Selector
就会很方便,例如:一个聊天服务器。
这是在一个单线程中使用一个Selector
处理3
个Channel
的图示:
要使用Selector
,得向Selector
注册Channel
,然后调用它的select()
方法。这个方法会一直阻塞到某个注册的通道有事件就绪。一旦这个方法返回,线程就可以处理这些事件。
事件类型主要包括:新连接进来、数据接收、数据发送等。
上面提到了NIO
主要的组件和特性,在实际的IO
操作中,应该如何在标准IO
和NIO
进行选择,这里就需要具体对比两者的差异,并引入一些概念。
IO | NIO | |
---|---|---|
底层读写实现 | 面向流读写 | 面向缓冲区读写 |
是否有选择器 | 无 | 基于选择器的事件分离 |
IO是否阻塞 | 阻塞式IO | 非阻塞式IO |
Java NIO
和IO
之间第一个最大的区别是,IO
是面向流的,NIO
是面向缓冲区的。
Java IO
面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方。此外,它不能前后移动流中的数据。如果需要前后移动从流中读取的数据,需要先将它缓存到一个缓冲区。
Java NIO
的缓冲导向方法略有不同。数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。这就增加了处理过程中的灵活性。但是,还需要检查是否该缓冲区中包含所有您需要处理的数据。而且,需确保当更多的数据读入缓冲区时,不要覆盖缓冲区里尚未处理的数据。
Java NIO
的选择器允许一个单独的线程来监视多个输入通道。
IO的读写速度和CPU的处理速度相差了一个数量级,导致IO事件延长了CPU的空闲等待时间,导致性能上的瓶颈。为了尽量的缩短CPU的等待时间,在单个IO操作进行时CPU可以抽出身来去做别的事情(其他IO),
NIO
引入单线程处理多IO事件的概念,从而充分利用CPU分配的资源。
Java NIO
允许已注册的多个通道使用一个选择器,然后使用一个单独的线程来选择通道。这种选择机制,使得一个单线程很容易地管理多个通道。
所谓阻塞,就是线程在进行IO
操作时,不能抽出身来去干其他事情,必须等待数据读写完成。
Java IO
的各种流是阻塞的。
read()
或write()
时,该线程被阻塞,直到有一些数据被读取,或数据完全写入。该线程在此期间不能再干任何事情。Java NIO
的非阻塞的。
线程通常将非阻塞IO
的空闲时间用于在其它通道上执行IO操作,所以一个单独的线程现在可以管理多个输入和输出通道(channel
)。
欢迎关注技术公众号: 零壹技术栈
本帐号将持续分享后端技术干货,包括虚拟机基础,多线程编程,高性能框架,异步、缓存和消息中间件,分布式和微服务,架构学习和进阶等学习资料和文章。
标签:异步 消息中间件 管理 之间 spl java 特性 sock 流量
原文地址:https://www.cnblogs.com/ostenant/p/9695172.html