目录 一、引言 二、IO 模式的特征 三、IO 三种模式 四、Netty 对三种 IO 模式的支持 五、Java NIO 核心组件 六、结语
一、引言在网络编程中,我们经常听到各种各样的名词:阻塞、非阻塞、异步、同步。这些,都是 IO 模式的特征。本篇说明了 IO 三种模式,以及简单提及了 NIO 的三大核心组件。 二、IO 模式的特征1、阻塞与非阻塞 2、同步与异步 同步:数据就绪后需要自己读。 异步:数据就绪后直接读好再回调给程序。
三、IO 三种模式名称 | 模式 | 备注 |
---|
BIO | 同步阻塞 | Blocking IO,始于 JDK 1.4 之前 | NIO | 同步非阻塞 | New IO 或 Non Blocking IO,始于 JDK 1.4 | AIO | 异步 | Async IO |
四、Netty 对三种 IO 模式的支持BIO -> OIO(Deprecated) | NIO | AIO(Removed) |
---|
Common | Linux | MacOS/BSD |
---|
ThreadPerChannelEventLoopGroup | NioEventLoopGroup | EpollEventLoopGroup | KQueueEventLoopGroup | AioEventLoopGroup | ThreadPerChannelEventLoop | NioEventLoop | EpollEventLoop | KQueueEventLoop | AioEventLoop | OioServerSocketChannel | NioServerSocketChannel | EpollServerSocketChannel | KQueueServerSocketChannel | AioServerSocketChannel | OioSocketChannel | NioSocketChannel | EpollSocketChannel | KQueueSocketChannel | AioSocketChannel |
由上面的表格可以看到 Netty 对于三种 IO 都是支持的,严谨的说是曾经支持过。 1、为什么 Netty 仅支持 NIO 了? 2、为什么 Netty 有多种 NIO 实现? NIO 有一个 Common 实现,针对不同的平台又有其相应的实现。通用的 NIO 实现在 Linux 下也是使用 epoll ,那么既然有了 Common 实现,为什么还要做不同的平台实现呢? ❤ tips:关于 epoll 的水平触发和边缘触发。 在 Linux 的网络编程中,内核使用 epoll 机制做事件触发,其中 epoll_wait 函数是 epoll 接口的三个函数之一,用于轮询I/O事件的发生。 水平触发通俗来讲:只要有数据,epoll_wait 函数就一直返回;边缘触发通俗来讲:只有 socket 状态发生变化,epoll_wait 函数才会返回。
关于 epoll 的更多,小伙伴若感兴趣可自行谷歌了解。 3、NIO 一定优于 BIO 吗? 相比较 NIO 而言,BIO 的代码实现简单,在特定连接数并发数少的场景下,BIO 的性能不输于 NIO 。 基于以上,学习 Netty 我们必须对 Java 的 NIO 有一定的基础,所以后面一些篇幅是对 Java 的 NIO 知识做一个回顾,即下面讲的 NIO 基于 Java 本身,与 Netty 无关,请小伙伴注意。 五、Java NIO 核心组件NIO 由三大核心组件组成: 传统 IO 基于流(Stream)操作,面向字节流或字符流。NIO 与之最大的不同就是基于 Channel 和 Buffer 操作,面向缓冲区。NIO 通过缓冲区可以读取任意位置的数据,相比传统 IO 灵活性大大增强,同时也不会阻塞当前线程。 1、Channel 不同于传统 IO 的流,读写需要使用不同的输入输出流,Channel 是双向的。这意味着它既可以用来进行读操作,又可以用来进行写操作。 NIO中的Channel的主要实现有: FileChannel DatagramChannel SocketChannel ServerSocketChannel
2、Buffer Buffer 是缓冲区,本质上是一块内存区域。NIO 中的关键 Buffer 实现有:ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer, LongBuffer, ShortBuffer,分别对应基本数据类型: byte, char, double, float, int, long, short。以及 MappedByteBuffer, HeapByteBuffer, DirectByteBuffer 等等。 3、Selector 一个 Selector 可以注册多个 Channel ,Selector 不断地执行查询并判断这些 Channel 是否存在已就绪的 IO 操作,如可读,可写,网络连接已完成等。通过这样的机制,单线程下一个 Selector 就可以管理多个 Channel 了。 六、结语本篇介绍了三种 IO 模式,以及 Netty 关于三种模式的一些问题讨论,并在结尾简单列举了 NIO 的核心组件,接下来我们将详细的了解 NIO 的核心组件,并学会如何使用它们。
|