IO和NIO
1.什么是阻塞和非阻塞?什么是同步和异步?
阻塞和非阻塞:
从线程的角度考虑 ,线程挂起 不在抢夺CPU 则称为线程被阻塞 同步和异步:
任务的执行需要相互等待、相互协调为同步;各执行各的,不管其他人,是异步。
2.解释一下什么是NIO?
是jdk1.4出现同步非阻塞式IO,它可以实现面向通道操作缓冲区,双向的传递数据,它适合在高并发的情况下使用,可以实现少量的线程为多个客户端服务。
3.NIO和IO有什么区别?
1) BIO: 面向流,操作字节字符,具有方向性,同步阻塞式IO 比喻:水管 InputStream OutputStream Reader Writer
2)NIO: 面向通道,操作缓冲区,可以双向传输数据,同步非阻塞式IO 比喻:地下通道 Channel Buffer Selector
4.NIO的常用API?
要实现NIO,主要就是操作它的三个API;
1)Channel 通道 可以实现双向传输数据
既能读,又能写,在使用的时候需要调用方法将其设置为false,即非阻塞模式;它有很多的实现类:
2)Buffer 缓冲区
在内存中开辟一段连续的空间,用于存储临时的数据。
常用的ByteBuffer,和CharBuffer,还有其它的用于不同的数据类型
所有的buffer都是抽象类,无法被直接实例化;
缓冲区的数据存放在内存中,能提高读写效率;
缓冲区有指针记录,能改变读写数据的起始点,处理灵活;
Buffer有几个基本的属性:capacity、Position、Limit、Mark
- Int Capacity()容量,缓冲区支持的最大容量
- Int Position()记录指针,缓冲区读写数据的起始点。开始为0,最大为limit
- Int Limit()界限,读写数据的终止点
- Mark标记,在0-positon,设置该值
缓冲区常用的方法:清除/反转/环绕/存放/取/存
- Clear()清空缓冲区,仅仅是移动position和limit,在往里写会覆盖原有的数据
- flip()实现反转缓冲区,确定缓存区的数据的起点和终止点
- Rewind() 重绕缓冲区,就是重新读一遍
- hasRemaining()判断positon和limit之间是否有元素
- Mark() 标记一个mark,随时可以回到这个标记
- Wrap()创建缓冲区
- Get()和put()获取元素和存放元素
3)Selector 选择器
多个客户端在Selector中注册自己,多个通道注册到Selector中,通过选择操作选出就绪的键,通道线程来实现少量线程的为多个客户端服务
用到的一些方法:
- register()方法;将通道注册到选择器中,
- Selector.open();获取选择器
- int select();选择器进行选择操作
- Set<SelectionKey> selectedKeys();获取已经就绪的键
5.什么是网络数据传输的粘包问题?
数据包之间发生的粘连问题,网络分为7层,每层负责每层的任务, TCP不理解应用层传输过来的数据
由于TCP传输是一种可靠的连续的数据传输,如果两次传输的数据时间间隔比较短,数据的接收方可能很难判断出两次数据的边界在哪里,感觉就好像两个数据黏着在了一次,无法区分。
粘包问题常用的解决办法:
1)每次传输固定大小的数据,存在资源浪费,缺乏灵活性
2)约定分隔符,如果符号相同,转义一下,需要解析,不是很好
3)使用协议,双方约定好
使用公开协议,或者私有的协议
在传输的过程中,先传递长度信息,在根据长度信息获取数据
6.IO图1
7.IO图2
推荐一篇好文章https://www.cnblogs.com/xiaoxi/p/6576588.html