NIO与BIO对比
(1)BIO是面向流,而NIO是面向缓冲区的,或者说BIO 以流的⽅式处理数据,⽽ NIO 以块的⽅式处理数据,块 I/O 的效率⽐流 I/O ⾼很多。
(2)BIO 是阻塞的, NIO 则是⾮阻塞的。
(3)BIO 基于字节流和字符流进⾏操作,⽽ NIO 基于 Channel (通道)和 Buffer (缓冲区)进⾏操作,数据总是从通道读取到缓冲区中,或者从缓冲区写⼊到通道中。 Selector (选择器)⽤于监听多个通道的事件(⽐如:连接请求,数据到达等),因此使⽤单个线程就可以监听多个客户端通道。
NIO核心原理
channel
1、每个 Channel 都会对应⼀个 Buffer 。
2、Selector 对应⼀个线程,⼀个线程对应多个 Channel (连接)。
3、该图反应了有三个 Channel 注册到该 Selector //程序
4、程序切换到哪个 Channel 是由事件决定的, Event 就是⼀个重要的概念。
5、Selector 会根据不同的事件,在各个通道上切换。
6、Buffer 就是⼀个内存块,底层是有⼀个数组。
7、数据的读取写⼊是通过 Buffer ,这个和 BIO , BIO 中要么是输⼊流,或者是输出流,不能双向,但是 NIO 的 Buffer 是可以读也可以写,需要 flip ⽅法切换 Channel 是双向的,可以返回底层操作系统的情况,⽐如 Linux ,底层的操作系统通道就是双向的。
BUFFER
Buffer 类定义了所有的缓冲区都具有的四个属性来提供关于其所包含的数据元素的信息:capacity(容量)、position(游标位置)、limit (末尾限定符),其中,position 和 limit 的意义依赖于当前 Buffer 是处于读模式还是写模式。capacity 的含义⽆论读写模式都是相同的。
选择器selector
选择器⽤于使⽤单个线程处理多个通道。因此,它需要较少的线程来处理这些通道。线程之间的切换对于操作系统来说是昂贵的。 因此,为了提⾼系统效率选择器是有⽤的。NIO有选择器,⽽IO没有。
Java 的 NIO ,⽤⾮阻塞的 IO ⽅式。可以⽤⼀个线程,处理多个的客户端连接,就会使⽤到Selector (选择器)。Selector 能够检测多个注册的通道上是否有事件发⽣(注意:多个 Channel 以事件的⽅式可以注册到同⼀个 Selector ),如果有事件发⽣,便获取事件然后针对每个事件进⾏相应的处理。
选择器的好处是可以只⽤⼀个单线程去管理多个通道,也就是管理多个连接和请求。只有在连接/通道真正有读写事件发⽣时,才会进⾏读写,就⼤⼤地减少了系统开销,并且不必为每个连接都创建⼀个线程,不⽤去维护多个线程。同时也避免了多线程之间的上下⽂切换导致的开销。