2023-09-23  阅读(3)
原文作者:李林超 原文地址: https://www.lilinchao.com/archives/2088.html

[TOC]

一、bytebuffer内部结构

1.1 属性介绍

Bytebuffer有以下重要属性:

  • capacity(容量) :缓冲区的容量。通过构造函数赋予,一旦设置,无法更改。
  • position(指针) :读写指针,记录数据读写的位置,缓冲区的位置不能为负,并且 不能大于limit
  • limit(读写限制) :缓冲区的界限。位于limit 后的数据不可读写。缓冲区的限制不能为负,并且 不能大于其容量

1.2 结构

  • 写模式

当缓冲区刚创建成功时

202309232223222051.png

写模式下,position 是写入位置,limit 等于容量。

下图表示写入了 4 个字节后的状态:

202309232223228932.png

Position移动到第5个字节开始位置

  • 读模式

flip动作发生后,position切换为读取位置,limit切换为读取限制

202309232223235933.png

  • position重新赋值到开始位置,因为读取数据从开始位置开始读取
  • limit被赋值为position写入时的最后位置,作为数据读取的最终位置

读取4个字节后,状态如下图:

202309232223242374.png

  • 当position位置与limit位置相同时,数据读取结束。
  • 数据未读取完重新切换到写模式时

compact 方法,是把未读完的部分向前压缩,然后切换至写模式

202309232223248545.png

二、ByteBuffer常见方法

  • put()

**描述:**可以将一个数据放入到缓冲区中。

进行该操作后,postition的值会+1,指向下一个可以放入的位置。capacity = limit ,为缓冲区容量的值。

202309232223255936.png

  • flip()

描述 :用来 切换对缓冲区的操作模式 ,由写->读 / 读->写

进行该操作后:

  • 如果是写模式->读模式,position = 0 , limit 指向最后一个元素的下一个位置,capacity不变;
  • 如果是读模式->写模式,则恢复为put()方法中的值。

202309232223261647.png

  • get()

描述 :该方法会读取缓冲区中的一个值

进行该操作后,position会+1,如果超过了limit则会抛出异常

202309232223269168.png

注意:get(i)方法不会改变position的值

  • rewind()

描述 :该方法 只能在读模式下使用

rewind()方法后,会恢复position、limit和capacity的值,变为进行get()前的值

202309232223275079.png

  • clean()

描述:会将缓冲区中的各个属性恢复为最初的状态,position = 0, capacity = limit

此时缓冲区的数据依然存在 ,处于“被遗忘”状态,下次进行写操作时会覆盖这些数据

2023092322232808110.png

  • mark()/reset()

描述 :mark 是在读取时,做一个标记,即使 position 改变,只要调用 reset 就能回到 mark 的位置

mark() :将postion的值保存到mark属性中

reset() :将position的值改为mark中保存的值

注意:rewind 和 flip 都会清除 mark 位置

  • compact()

描述 :compact会把未读完的数据向前压缩,然后切换到写模式

数据前移后,原位置的值并未清零,写时会 覆盖 之前的值

2023092322232865811.png

注意:此方法为ByteBuffer的方法,而不是Buffer的方法

clear()和compact()方法对比:

clear只是对position、limit、mark进行重置,而compact在对position进行设置,以及limit、mark进行重置的同时,还涉及到数据在内存中拷贝(会调用arraycopy)。**所以compact比clear更耗性能。**但compact能保存你未读取的数据,将新数据追加到为读取的数据之后;而clear则不行,若你调用了clear,则未读取的数据就无法再读取到了

需要根据情况来判断使用哪种方法进行模式切换

附参考文章:

《黑马程序员Netty教程》


Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。

它的内容包括:

  • 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
  • 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
  • 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
  • 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
  • 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
  • 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
  • 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
  • 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw

目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:

想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询

同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。

阅读全文