netty-第一部分-NIO
为什么学netty先学NIO
Netty是基于Java NIO的,我们首先来看一下NIO的基本概念与使用,才能在学习Netty的时候知道它做了哪些优化,到底哪里好。所以我们先来看NIO的三个核心概念。
NIO的三个核心概念
- Channel
- Buffer
- Selector
1 Channel
翻译过来就是通道。
相当于我们在两个文件存储的位置搭上了桥。让数据从一边流向另一边。
常见的有FileChannel,SocketChannel。
FileChannel一般用于文件的读写。
SocketChannel是针对socket的Channel,后续会详细讲解。
Channel一般配合ByteBuffer缓冲区使用(我们目前可以简单的把ByteBuffer看做一个字节数组)
例如读操作
FileChannel就是把文件内容数据读到ByteBuffer中
SocketChannel就是把网络传输过来的数据读到ByteBuffer中
这里简单聊一下FileChannel的使用,二者同为Channel,都是传输通道的思想
比如我想从一个文件a.txt
中读到一个我声明的ByteBuffer
中
String aPath = "qwe/a.txt";//a.txt文件路径
ByteBuffer buffer = ByteBuffer.allocate(10);//10个字节的ByteBuffer
channel.read(buffer);//把文件中内容读到我的buffer中
上面实例仅仅是一个Demo,并不完整,如果读取文件,还需要做异常处理,并且由于ByteBuffer容量有限,我们可能要分多次读取。当然这里仅仅是展示一下简单的Channel使用,只把主要部分写出来了。
2 Buffer
缓存,我们读到的数据或者要写的数据需要先有个地方存放。我们用它暂存我们读到的数据或者要写的数据。
常见的有ByteBuffer,ShortBuffer等。
本篇只是介绍一下概念,后续会详细讲解ByteBuffer。
3 Selector
如果没学习过IO模型相关知识,可能较难理解,我尽量简短清晰的写明它的作用,不引入过多的陌生概念。
我们使用SocketChannel处理连接,每个连接对应一个SocketChannel。
比如有三台pc,主机a做服务器,b和c都和a建立tcp连接。我们就用SocketChannel管理单个连接,所以我们这里有两个SocketChannel,我们称为p和q。
显而易见,建立连接后是服务器客户端收发数据的阶段。我们需要用一个线程来管理一个SocketChannel。当某个连接要读或者写数据时,我们通过SocketChannel就能得知,满足客户端的需要。这样就有个问题,我们有很多连接,就有很多个SocketChannel,难道我们要大量线程来处理吗,这样涉及线程上下文的频繁切换,同时cpu核数有限,所以能处理的连接数也很有限。
我们来考虑优化,因为一个连接上大概率是不会一直处于有事件的状态,我们只需要在有事件是分配线程来处理,平时使用一个监听器来监听所有连接的SocketChannel即可。这就是Selector的原理。当然这只是为了方便才把这个过程描述的较为简单,后续会详解Selector。目前我们只需要知道它的作用是用一个线程来管理多个Channel。
结语
上面就是三个Java NIO的核心概念,后面文章会对三者做详细分析。
其实NIO已经学完三天了,但是一直没写,今天才写出来。写的时候发现要写好久,这一篇介绍就写了一个小时左右。明天还有个面试,尽量明天后天集中把NIO部分写完。毕竟主要学习Netty,太多时间花在NIO上不太合理。
今天一看上篇文章居然有7个点赞哈哈,我还以为都不会有人看呢,写的东西有人看感觉很高兴,希望以后能给大家带来更多好的文章吧。
感谢大家观看。