1. NIO和BIO的比较
BIO以流的方式处理数据,而NIO以块的方式处理数据,块I/O的效率比流I/O高很多。
BIO是阻塞的,NIO是非阻塞的
BIO基于字节流和字符流进行操作,而NIO是基于Channel(通道)和Buffer(缓冲区)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中
Selector(选择器)用于监听多个通道的事件,(比如连接请求,数据到达等)因此使用单个线程就可以监听多个客户端通道。
2. NIO中三大组件关系
nio三大组件:channel、buffer、selector
每个channel都会对应一个Buffer
Selector都对应一个线程,一个线程对应多个channel(连接)
该图反应了有三个channel注册到该selector中
程序切换到哪个channel是由事件决定的,Event就是一个重要的概念。
selector会根据不同的事件,在各个通道上切换。
buffer就是一个内存块,底层有一个数组。
数据的读取写入是通过buffer,这个和BIO本质不同,BIO中要么是输入流或者是输出流,不会是双向的,而NIO中的buffer可读可写,需要flip方法切换。
channel是双向的,可以返回底层操作系统的情况,如linux,底层的操作系统就是双向的
与netty有什么关系
Netty的IO线程 NioEventLoop 聚合了 Selector(选择器,也叫多路复用器),可以同时并发处理成百上千个客户端连接。
当线程从某客户端 Socket 通道进行读写数据时,若没有数据可用时,该线程可以进行其他任务。
线程通常将非阻塞IO的空闲时间用于在其他通道上执行 IO 操作,所以单独的线程可以管理多个输入和输出通道。
由于读写操作都是非阻塞的,这就可以充分提升 IO 线程的运行效率,避免由于频繁 I/O 阻塞导致的线程挂起。
一个I/O线程可以并发处理N个客户端连接和读写操作,这从根本上解决了传统同步阻塞I/O一连接一线程模型,架构的性能、弹性伸缩能力和可靠性都得到了极大的提升
Selector、selectionKey、ServerSocketChannel和SocketChannel关系梳理图。
当客户端连接时,会通过ServerSocketChannel得到SocketChannel
将socketChannel注册到Selector上,regist(Slector sel,int ops),一个selector上可以注册多个SocketChannel。
注册后返回一个SelectionKey,回纥该Selector关联(集合)
Selector进行监听select方法,返回有事件发生通道的个数
进一步得到各个 SelectionKey (有事件发生)
再通过SelectionKey反向获取 SocketChannel,方法 channel()
可以通过 得到的 channel , 完成业务处理