【Netty】Netty入坑:一、全网最清晰图解、NIO简单介绍

一、什么是Java NIO 的非阻塞模式

  • 连接层(即Selector层,所谓的多路复用):

一个线程,从某通道发送请求或者读取数据的时候,它仅能得到当前可用的数据。

如果当前没有数据可用的话,就什么都不获取。并且它不会阻塞起来,他可以去轮训其他通道,

直达当前通道有数据变动之前,它都可以去做其他事情,或者说它都可以去轮训其他通道。

   

  • I/O层(即Buffer层):

当某一个通道有数据传输过来,要求我们写入的时候,我们不需要等到线程将当前任务数据完全写入后,

再去进行当前通道的其他读/写操作,可以对其他任务既处理读、又处理写操作(一个通道会有可能产生多个任务,但是只对应一个Buffer),

可以灵活的处理当前通道数据,即在写入本任务的同时,也可以同时去当前通道其他任务数据读写,使得当前通道其他任务不会一直阻塞在那里。

  • 连接层和IO层,既可以用同一个线程处理(此处说明该线程不会阻塞),也可以用多个线程处理。

二、BIO和NIO区别:

1》BIO是以流的方式处理数据,而NIO以块的方式处理数据,块IO效率要比流IO效率高很多。

2》BIO是阻塞的,NIO是非阻塞的

3》BIO基于字节流和字符流操作,而NIO基于Channel(通道)和Buffer(缓冲区)进行操作。

  采用Selector轮训监听多个通道的时间,以达单个线程可以监听多个客户端通道。
  • 字节流、字符流,两类都分为输入和输出操作,这里简单说一下字节流和字符流的概念 :

1》 在字节流中输出数据主要是使用OutputStream完成,输入使的是InputStream

     在字符流中输出主要是使用Writer类完成,输入流主要使用Reader类完成。

2》字节流在操作的时候本身是不会用到缓冲区(内存)的,是与文件本身直接操作的,而字符流在操作的时候是使用到缓冲区的

3》字节流可用于任何类型的对象,包括二进制对象,而字符流只能处理字符或者字符串,但如果是Unicode字符的话,只能使用字符流进行处理;

具体参考如下:字节(byte)、二进制、字节流、字符流相关概念分析

三、一张图来描述NIO的Selector、Channel和Buffer的关系:

1》每个channel都会对应一个buffer

2》Selector对应一个线程,一个Selector可以对应多个channel连接,也就说明一个线程可以处理多个channel连接

3》图中说明有3个channel注册到Selector

4》程序切换到哪个Channel是有事件(Event)决定的,Event是一个很重要的概念,也就是说NIO是事件驱动的

5》Selector会根据不同的事件,在各个不同的Channel通道上切换

6》Buffer就是一个内存块,底层其实有一个数组

7》数据的读取和写入都是通过Buffer,这个和BIO是有区别的。

   BIO中要么是输入流,要么是输出流(即都是单向的),不能双向处理。

   但是NIO中Buffer可以在读的同时,去操作写操作,不过需要flip方法切换。

8》Channel也是双向的。可以返回底层操作系统的情况,比如Linux,底层操作系统通道都就是双向的。
学而不思则罔 思而不学则殆 !
原文地址:https://www.cnblogs.com/boluopabo/p/14308944.html