non-blocking io 非阻塞IO
1、三大组件
1.1Channel & Buffer
Channel有一点类似于stream,它就是读取数据的**双向通道,**可以从Channel将数据读入buffer,也可以将buffer的数据写入channel,而之前的stream要么是输入,要么输出,channel比stream更为底层
常见的Channel有
- FileChannel(做文件的通道)
- DatagramChannel(做udp时的网络传输通道)
- SocketChannel(TCP传输通道)
- ServerSocketChanne(TCP传输通道-专用于服务器)
buffer则用来缓存冲读取数据,常见的buffer有
- ByteBuffer
- MappedByteBuffer
- DirectByteBuffer
- HeapByteBuffer
ByteBuffer大小分配
- 每个channel都需要记录可能被切分的消息,因为ByteBuffer不能被多个channel共同使用,因此需要为每个channel维护一个独立的ByteBuffer
- ByteBuffer不能太大,比如一个ByteBuffer 1Mb的话,要支持百万连接就要1Tb内存,因此需要设计大小可变的ByteBuffer
- 一种思路是首先分配一个较小的buffer,例如4k,如果发现数据不够,再分配8k的buffer,将4kbuffer内容拷贝到8k buffer,优点是消息连续容易处理,缺点是数据拷贝耗费性能
- 另一种思路是用多个数组组成buffer,一个数组不够,把多出来的内容写入新的数组,与前面的区别是消息存储不连续解析复杂,优点是避免了拷贝引起的性能损耗
1.2 Selector
最初的版本设计:多线程版
- [ ] 多线程版缺点
- 内存占用高
- 线程上下文切换成本高
- 只适合连接数少的场景
线程池版本
- [ ] 线程池版缺点
- 阻塞模式下,线程仅仅能处理一个socket连接
- 仅适合短连接场景(如http)
selector版设计
调用selector的serect()会阻塞直到chanel发生了读写就绪事件,这些事件发生,select方法就会返回这些事件交给thread来处理
-------需要看后面内容请看主页查看下一篇 ---------