本文来说下NIO的原理和机制
首先说一下核心区别:
通道是个什么意思
设计原理详解。先来了解一下buffer的工作机制:
1、这一步其实是当我们刚开始初始化这个buffer数组的时候,开始默认是这样的
2、但是当你往buffer数组中开始写入的时候几个字节的时候就会变成下面的图,position会移动你数据的结束的下一个位置,这个时候你需要把buffer中的数据写到channel管道中,所以此时我们就需要用这个buffer.flip();方法,
3、当你调用完2中的方法时,这个时候就会变成下面的图了,这样的话其实就可以知道你刚刚写到buffer中的数据是在position---->limit之间,然后下一步调用clear();
4、这时底层操作系统就可以从缓冲区中正确读取这 5 个字节数据发送出去了。在下一次写数据之前我们在调一下 clear() 方法。缓冲区的索引状态又回到初始位置。(其实这一步有点像IO中的把转运字节数组 char[] buf = new char[1024]; 不足1024字节的部分给强制刷新出去的意思)
补充:
nio核心组件、1、这里还要说明一下 mark,当我们调用 mark() 时,它将记录当前 position 的前一个位置,当我们调用 reset 时,position 将恢复 mark 记录下来的值
2、clear()方法会:清空整个缓冲区。position将被设回0,limit被设置成 capacity的值(这个个人的理解就是当你在flip()方法的基础上已经记住你写入了多少字节数据,直接把position到limit之间的也就是你写入已经记住的数据给“复制”到管道中)
3、当你把缓冲区的数局写入到管道中的时候,你需要调用flip()方法将Buffer从写模式切换到读模式,调用flip()方法会将position设回0,并将limit设置成之前position的值。buf.flip();(其实我个人理解的就相当于先记住缓冲区缓冲了多少数据)
public void selector() throws IOException {
//先给缓冲区申请内存空间ByteBuffer buffer = ByteBuffer.allocate(1024);//打开Selector为了它可以轮询每个 Channel 的状态Selector selector = Selector.open();ServerSocketChannel ssc = ServerSocketChannel.open();ssc.configureBlocking(false);//设置为非阻塞方式ssc.socket().bind(new InetSocketAddress(8080));ssc.register(selector, SelectionKey.OP_ACCEPT);//注册监听的事件while (true) {Set selectedKeys = selector.selectedKeys();//取得所有key集合Iterator it = selectedKeys.iterator();while (it.hasNext()) {SelectionKey key = (SelectionKey) it.next();if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) {ServerSocketChannel ssChannel = (ServerSocketChannel) key.channel();SocketChannel sc = ssChannel.accept();//接受到服务端的请求sc.configureBlocking(false);sc.register(selector, SelectionKey.OP_READ);it.remove();} else if((key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) {SocketChannel sc = (SocketChannel) key.channel();while (true) {buffer.clear();int n = sc.read(buffer);//读取数据if (n <= 0) {break;}buffer.flip();}it.remove();}}}
}
本文详细介绍了NIO相关的知识。
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态