AbstractReferenceCountedByteBuf源码分析

来源:互联网 发布:南城整形医院知美 编辑:程序博客网 时间:2024/06/14 05:00

1.成员变量

 private static final AtomicIntegerFieldUpdater<AbstractReferenceCountedByteBuf> refCntUpdater;    static {        AtomicIntegerFieldUpdater<AbstractReferenceCountedByteBuf> updater =                PlatformDependent.newAtomicIntegerFieldUpdater(AbstractReferenceCountedByteBuf.class, "refCnt");        if (updater == null) {            updater = AtomicIntegerFieldUpdater.newUpdater(AbstractReferenceCountedByteBuf.class, "refCnt");        }        refCntUpdater = updater;    }    private volatile int refCnt = 1

AtomicIntegerFieldUpdater是什么鬼?先研究一下atomic包下的两个重要的类
1.AtomicInteger的使用
AtomicInteger ℹ=new AtimicInteger(0);
这样变量i就有了原子性

2.AtomicintegerFieldUpdater的使用
public static AtomicIntegerFieldUpdaternewUpdater(Class tclass,
String fieldName)
这里就不详细分析他的源码了,其实很简单,他让tclass的成员fieldName具有了原子性,是不是很简单~

研究完再回来看他的成员变量,实在不能太简单。
AbstractReferenceCountedByteBuf源码实现,该类主要是实现引用计算的常规方法,充分利用voliate内存可见性与CAS操作完成refCnt变量的维护。

2.实现的函数

在这个类的函数中,看到了很熟悉的东西release(),retain(),refcnt(),touch()这些方法,天呐,这不就是ByteBuf类,AbstarctByteBuf类中没有实现的方法吗?原来都拿到这里来实现了。上代码!

 @Override    public ByteBuf retain() {        for (;;) {            int refCnt = this.refCnt;            if (refCnt == 0) {                throw new IllegalReferenceCountException(0, 1);            }            if (refCnt == Integer.MAX_VALUE) {                throw new IllegalReferenceCountException(Integer.MAX_VALUE, 1);            }            if (refCntUpdater.compareAndSet(this, refCnt, refCnt + 1)) {                break;            }        }        return this;    }

每调用一次retain方法,计数器加一
compareAndSet方法用来获取自己的值和期望的值进行比较,如果其间被其他线程修改了,那么比对失败,进行自旋操作,重新获得计数器重新比较
compareAndSet这个方法是CAS操作,由操作系统层面提供。

 @Override    public final boolean release() {        for (;;) {            int refCnt = this.refCnt;            if (refCnt == 0) {                throw new IllegalReferenceCountException(0, -1);            }            if (refCntUpdater.compareAndSet(this, refCnt, refCnt - 1)) {                if (refCnt == 1) {                    deallocate();                    return true;                }                return false;            }        }    }

每调用一次release方法,计数器减1
同样用compareAndSet进行自旋操作。

原创粉丝点击