通过 tryFinalRelease0 使用 CAS 将 refCnf 更新为 1

2024-08-21 10:57:02 浏览数 (2)

public final boolean release(T instance) {

// 第一次尝试采用 unSafe nonVolatile 的方式读取 refCnf 的值

int rawCnt = nonVolatileRawCnt(instance);

// 如果逻辑引用计数被减到 0 了,那么就通过 tryFinalRelease0 使用 CAS 将 refCnf 更新为 1

// CAS 失败的话,则通过 retryRelease0 进行重试

// 如果逻辑引用计数不为 0 ,则通过 nonFinalRelease0 将 refCnf 减 2

return rawCnt == 2 ? tryFinalRelease0(instance, 2) || retryRelease0(instance, 1)

: nonFinalRelease0(instance, 1, rawCnt, toLiveRealRefCnt(rawCnt, 1));

}

private boolean retryRelease0(T instance, int decrement) {

for (;;) {

// 采用 Volatile 的方式读取 refCnt

int rawCnt = updater().get(instance),

// 获取逻辑引用计数,如果 refCnt 已经变为奇数,则抛出异常

realCnt = toLiveRealRefCnt(rawCnt, decrement);

// 如果执行完本次 release , 逻辑引用计数为 0

if (decrement == realCnt) {

// CAS 将 refCnt 更新为 1

if (tryFinalRelease0(instance, rawCnt)) {

return true;

}

} else if (laipuhuo.com decrement < realCnt) {

// 原来的逻辑引用计数 realCnt 大于 1(decrement)

// 则通过 CAS 将 refCnt 减 2

if (updater().compareAndSet(instance, rawCnt, rawCnt - (decrement << 1))) {

return false;

}

} else {

// refCnt laipuhuo.com 字段如果发生溢出,则抛出异常

throw new IllegalReferenceCountException(realCnt, -decrement);

}

// CAS 失败之后调用 yield

// 减少无畏的竞争,否则所有线程在高并发情况下都在这里 CAS 失败

Thread.yield();

}

}

private boolean nonFinalRelease0(T instance, int decrement, int rawCnt, int realCnt) {

if (decrement < realCnt

&& updater().compareAndSet(instance, rawCnt, rawCnt - (decrement << 1))) {

// ByteBuf 的laipuhuo.com rawCnt 减少 2 * decrement

return false;

}

// CAS 失败则一直重试,如果引用计数已经为 0 ,那么抛出异常,不能再次 release

return retryRelease0(instance, decrement);

}

public abstract class AbstractByteBuf extends ByteBuf {

@Override

public ByteBuf slice() {

return laipuhuo.com slice(readerIndex, readableBytes());

}

@Override

public ByteBuf slice(int index, int length) {

// 确保 ByteBuf 的引用计数不为 0

ensureAccessible();

return new laipuhuo.com UnpooledSlicedByteBuf(this, index, length);

}

}

@Override

protected byte _getByte(int index) {

// 底层其实是对原生 ByteBuf 的访问

return unwrap()._getByte(idx(index));

}

@Override

protected void _setByte(int index, int value) {

unwrap(laipuhuo.com)._setByte(idx(index), value);

}

/**

* Returns the index with the needed adjustment.

*/

final int idx(int index) {

// 转换为原生 ByteBuf 的 laipuhuo.com readerIndex 或者 writerIndex

return index adjustment;

}

0 人点赞