Java NIO

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jcsyl_mshot/article/details/79979741

在 NIO 中有几个核心对象:缓冲区(Buffer)、通道(Channel)、选择器(Selector)。

一. 缓冲区(Buffer)

缓冲区实际上是一个容器对象, 其实就是一个数组, 在 NIO 库中, 所有数据都是用缓冲区处理的。 在读取数据时, 它是直接读到缓冲区中的; 在写入数据时, 它也是写入到缓冲区中的; 任何时候访问 NIO 中的数据, 都是将它放到缓冲区中**。 在 NIO 中, 所有的缓冲区类型都继承于抽象类 Buffer, 最常用的就是 ByteBuffer。
而在面向流 I/O 系统中, 所有数据都是直接写入或者直接将数据读取到
Stream 对象中。

二. 通道(Channel)

通道是一个对象, 通过它可以读取和写入数据, 所有数据都通过 Buffer 对象来处理。 我们永远不会将字节直接写入通道中, 相反是将数据写入包含一个或者多个字节的缓冲区。 同样不会直接从通道中读取字节, 而是将数据从通道读入缓冲区, 再从缓冲区获取这个字节。 通道与流的不同之处在于通道是双向的。 而流只是在一个方向上移动(一个流必须是 InputStream 或者OutputStream 的子类, 比如 InputStream 只能进行读取操作, OutputStream 只能进行写操作), 而通道是双向的, 可以用于读、 写或者同时用于读写。

三. 选择器(Selector)

NIO 有一个主要的类 Selector,这个类似一个观察者, 只要我们把需要探知的 socketchannel 告诉 Selector,我们接着做别的事情, 当有事件发生时, 他会通知我们, 传回一组 SelectionKey,我们读取这些 Key,就会获得我们刚刚注册过的 socketchannel,然后, 我们从这个 Channel 中读取数据, 放心, 包准能够读到, 接着我们可以处理这些数据。
Selector 内部原理实际是在做一个对所注册的 channel 的轮询访问, 不断地轮询, 一旦轮询到一个 channel 有所注册的事情发生, 比如数据来了, 他就会站起来报告, 交出一把钥匙, 让我们通过这把钥匙来读取这个 channel 的内容。
Selector 的作用就是用来轮询每个注册的 Channel,一旦发现 Channel 有注册的事件发生, 便获取事件然后进行处理。 用单线程处理一个 Selector,然后通过Selector.select()方法来获取到达事件, 在获取了到达事件之后, 就可以逐个地对这些事件进行响应处理。就大大地减少了系统开销, 并且不必为每个连接都创建一个线程, 不用去维护多个线程, 并且避免了多线程之间的上下文切换导致的开销。

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页