大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺
Jdk注释翻译
/**
*返回ByteBuf的可读字节的拷贝。修改返回的ByteBuf内容与当前ByteBuf完全不会相互影响。
*此方法不会修改当前ByteBuf的readerIndex或writerIndex
**/
public abstract ByteBuf copy();
/**
*返回ByteBuf可读字节的一部分。 修改返回的ByteBuf或当前ByteBuf会影响彼此的内容,
*同时它们维护单独的索引和标记,此方法不会修改当前ByteBuf的readerIndex或writerIndex
*另请注意,此方法不会调用{@link #retain()},因此不会增加引用计数。
**/
public abstract ByteBuf duplicate();
/**
*返回共享当前ByteBuf信息的新ByteBuf,他们使用独立的readIndex writeIndex markIndex
*修改返回的ByteBuf或当前ByteBuf会影响彼此的内容,同时它们维护单独的索引和标记,
*此方法不会修改当前ByteBuf的readerIndex或writerIndex,
*另请注意,此方法不会调用{@link #retain()},因此不会增加引用计数
**/
public abstract ByteBuf slice();
实验验证
public class ByteBufTest {
public static void main(String[] args) throws UnsupportedEncodingException {
ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(10);
byteBuf.writeInt(126);
byteBuf.writeInt(127);
byteBuf.writeBytes(new byte[]{1});
System.out.println("byteBuf readInt="+byteBuf.readInt());
System.out.println("byteBuf readerIndex=" + byteBuf.readerIndex() + "| writeIndex=" + byteBuf.writerIndex() + "|capacity=" + byteBuf.capacity());
//返回ByteBuf的可读字节的拷贝。修改返回的ByteBuf内容与当前ByteBuf完全不会相互影响。
//此方法不会修改当前ByteBuf的readerIndex或writerIndex
System.out.println("====================byteBuf.copy()==================");
ByteBuf cByteBuf = byteBuf.copy();
System.out.println("cByteBuf readerIndex=" + cByteBuf.readerIndex() + "| writeIndex=" + cByteBuf.writerIndex() + "|capacity=" + cByteBuf.capacity());
System.out.println("byteBuf readerIndex=" + byteBuf.readerIndex() + "| writeIndex=" + byteBuf.writerIndex() + "|capacity=" + byteBuf.capacity());
System.out.println("向cByteBuf中写入数据" + cByteBuf.setInt(0, 128));
System.out.println("cByteBuf=" + cByteBuf.getInt(0) + "|cByteBuf=" + cByteBuf.getByte(4));
System.out.println("byteBuf=" + byteBuf.getInt(0) + "|byteBuf=" + byteBuf.getInt(4) + "|byteBuf=" + byteBuf.getByte(8));
//返回ByteBuf可读字节的一部分。 修改返回的ByteBuf或当前ByteBuf会影响彼此的内容,
// 同时它们维护单独的索引和标记,此方法不会修改当前ByteBuf的readerIndex或writerIndex
//另请注意,此方法不会调用{@link #retain()},因此不会增加引用计数。
System.out.println("====================byteBuf.slice()==================");
ByteBuf sByteBuf = byteBuf.slice();
System.out.println("sByteBuf readerIndex=" + sByteBuf.readerIndex() + "| writeIndex=" + sByteBuf.writerIndex() + "|capacity=" + sByteBuf.capacity());
System.out.println("byteBuf readerIndex=" + byteBuf.readerIndex() + "| writeIndex=" + byteBuf.writerIndex() + "|capacity=" + byteBuf.capacity());
System.out.println("向sByteBuf中写入数据" + sByteBuf.setInt(0, 128));
System.out.println("sByteBuf=" + sByteBuf.getInt(0) + "|sByteBuf=" + sByteBuf.getByte(4));
System.out.println("byteBuf=" + byteBuf.getInt(0) + "|byteBuf=" + byteBuf.getInt(4) + "|byteBuf=" + byteBuf.getByte(8));
//返回共享当前ByteBuf信息的新ByteBuf,他们使用独立的readIndex writeIndex markIndex
//修改返回的ByteBuf或当前ByteBuf会影响彼此的内容,同时它们维护单独的索引和标记,
// 此方法不会修改当前ByteBuf的readerIndex或writerIndex,
//另请注意,此方法不会调用{@link #retain()},因此不会增加引用计数。
System.out.println("====================byteBuf.duplicate()==================");
ByteBuf dByteBuf = byteBuf.duplicate();
System.out.println("dByteBuf readerIndex=" + dByteBuf.readerIndex() + "| writeIndex=" + dByteBuf.writerIndex() + "|capacity=" + dByteBuf.capacity());
System.out.println("byteBuf readerIndex=" + byteBuf.readerIndex() + "| writeIndex=" + byteBuf.writerIndex() + "|capacity=" + byteBuf.capacity());
System.out.println("向dByteBuf中写入数据" + dByteBuf.setInt(0, 100));
System.out.println("dByteBuf=" + dByteBuf.getInt(0) + "|dByteBuf=" + dByteBuf.getInt(4) + "|dByteBuf=" + dByteBuf.getByte(8));
System.out.println("byteBuf=" + byteBuf.getInt(0) + "|byteBuf=" + byteBuf.getInt(4) + "|byteBuf=" + byteBuf.getByte(8));
dByteBuf.writeBytes(new byte[]{2});
System.out.println("dByteBuf readerIndex=" + dByteBuf.readerIndex() + "| writeIndex=" + dByteBuf.writerIndex() + "|capacity=" + dByteBuf.capacity());
System.out.println("byteBuf readerIndex=" + byteBuf.readerIndex() + "| writeIndex=" + byteBuf.writerIndex() + "|capacity=" + byteBuf.capacity());
System.out.println("dByteBuf=" + dByteBuf.getInt(0) + "|dByteBuf=" + dByteBuf.getInt(4) + "|dByteBuf=" + dByteBuf.getByte(8) + "|dByteBuf=" + dByteBuf.getByte(9));
System.out.println("byteBuf=" + byteBuf.getInt(0) + "|byteBuf=" + byteBuf.getInt(4) + "|byteBuf=" + byteBuf.getByte(8) + "|byteBuf=" + dByteBuf.getByte(9));
}
}
执行结果:
byteBuf readInt=126
byteBuf readerIndex=4| writeIndex=9|capacity=10
====================byteBuf.copy()==================
cByteBuf readerIndex=0| writeIndex=5|capacity=5
byteBuf readerIndex=4| writeIndex=9|capacity=10
向cByteBuf中写入数据PooledUnsafeDirectByteBuf(ridx: 0, widx: 5, cap: 5)
cByteBuf=128|cByteBuf=1
byteBuf=126|byteBuf=127|byteBuf=1
====================byteBuf.slice()==================
sByteBuf readerIndex=0| writeIndex=5|capacity=5
byteBuf readerIndex=4| writeIndex=9|capacity=10
向sByteBuf中写入数据UnpooledSlicedByteBuf(ridx: 0, widx: 5, cap: 5/5, unwrapped: PooledUnsafeDirectByteBuf(ridx: 4, widx: 9, cap: 10))
sByteBuf=128|sByteBuf=1
byteBuf=126|byteBuf=128|byteBuf=1
====================byteBuf.duplicate()==================
dByteBuf readerIndex=4| writeIndex=9|capacity=10
byteBuf readerIndex=4| writeIndex=9|capacity=10
向dByteBuf中写入数据UnpooledDuplicatedByteBuf(ridx: 4, widx: 9, cap: 10, unwrapped: PooledUnsafeDirectByteBuf(ridx: 4, widx: 9, cap: 10))
dByteBuf=100|dByteBuf=128|dByteBuf=1
byteBuf=100|byteBuf=128|byteBuf=1
dByteBuf readerIndex=4| writeIndex=10|capacity=10
byteBuf readerIndex=4| writeIndex=9|capacity=10
dByteBuf=100|dByteBuf=128|dByteBuf=1|dByteBuf=2
byteBuf=100|byteBuf=128|byteBuf=1|byteBuf=2
小结:
- duplicate():直接拷贝整个buffer,包括readerIndex、capacity、writerIndex
- slice():拷贝buffer中已经写入数据的部分
- copy()方法会进行内存复制工作,效率很低。
duplicate和copye这两个方法都属于浅拷贝它和原buffer是共享数据的。所以说调用这些方法消耗是很低的,
并没有开辟新的空间去存储,但是修改后会影响原buffer。这就会导致一个问题:在源ByteBuf调用release() 之后,
一旦引用计数为零,就变得不能访问了;在这种场景下,源ByteBuf的所有浅层复制实例也不能进行读写了;如果强行对浅层复制实例进行读写,则会报错。因此,在调用浅层复制实例时,可以通过调用一次retain() 方法来增加引用,表示它们对应的底层内存多了一次引用,引用计数为2。在浅层复制实例用完后,需要调用两次release()方法,将引用计数减一,这样就不影响源ByteBuf的内存释放。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/191970.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...