store模块阅读6:ReferenceResource

2017-10-13  本文已影响108人  赤子心_d709

说明

MappedFile父类,作用是记录MappedFile中的引用次数
为正表示资源可用,刷盘前加一,然后将wrotePosotion的值赋给committedPosition,再减一。

主要函数简介如下:

hold函数:引用,使得引用次数 +1
release:释放引用,引用次数-1
shutdown:关闭资源,清理

下面先贴源码后分析

源码

public abstract class ReferenceResource {
    protected final AtomicLong refCount = new AtomicLong(1);//引用计数,>0可用, <=0不可用
    protected volatile boolean available = true;//是否可用
    protected volatile boolean cleanupOver = false;//是否清理干净
    private volatile long firstShutdownTimestamp = 0;//第一次shutdown时间

    /**
     * 和release函数搭配使用
     * 占用资源,refCount + 1
     */
    public synchronized boolean hold() {
        if (this.isAvailable()) {
            if (this.refCount.getAndIncrement() > 0) {
                return true;
            } else { //不会出现的!!!
                this.refCount.getAndDecrement();
            }
        }

        return false;
    }

    public boolean isAvailable() {
        return this.available;
    }

    /**
     * 参数 intervalForcibly 代表强制间隔,即两次生效的间隔至少要有这么大(不是至多!!!)
     * 第一次调用时available设置为false,设置初始时间,释放一个引用
     * 之后再调用的时候,如果refCount > 0,且超过了强制间隔,则设置为一个负数,释放一个引用
     *
     * 备注:如果在intervalForcibly时间内再次shutdown 代码不会执行任何逻辑
     */
    public void shutdown(final long intervalForcibly) {
        if (this.available) {
            this.available = false;//改为不可用
            this.firstShutdownTimestamp = System.currentTimeMillis();
            this.release();//释放一个引用
        } else if (this.getRefCount() > 0) {//若引用数还>0
            if ((System.currentTimeMillis() - this.firstShutdownTimestamp) >= intervalForcibly) {//要超过强制间隔的阈值才行
                this.refCount.set(-1000 - this.getRefCount());
                this.release();
            }
        }
    }

    /**
     * 和hold函数搭配
     * 释放一个引用,计数-1
     * 若计数 <=0,则调用cleanup,子类实现
     */
    public void release() {
        long value = this.refCount.decrementAndGet();
        if (value > 0)
            return;
        // <=0则清理
        synchronized (this) {

            this.cleanupOver = this.cleanup(value);
        }
    }

    public long getRefCount() {
        return this.refCount.get();
    }

    public abstract boolean cleanup(final long currentRef);

    public boolean isCleanupOver() {//引用数<=0 且 cleanupOver为true
        return this.refCount.get() <= 0 && this.cleanupOver;
    }
}

分析,备注

available和refCount值

available = true && refCount >0 :正常被引用状态
available = true && refCount <=0 : 不会出现
available = false && refCount >0 : 刚调用shutDown,还没清干净
available = false && refCount <=0 : 在intervalForcibly时间内清理干净 或者 超出了intervalForcibly时间后再次清理

refCount为正数时是准确引用次数

正常的使用方法

      if(this.hold()) {
          //logic
          this.release();
      }
     
      最终在其他函数执行this.shutdown(intervalForcibly)

这样使得refCount 从1开始,以0结束

shutdown函数的intervalForcibly参数

如果在intervalForcibly时间内再次shutdown 代码不会执行任何逻辑
intervalForcibly表示两次清理之间至少要隔的时间,不是至多

吐槽

hold函数里面else是不会出现的.

refer:

https://juejin.im/entry/5987c5e951882526201acd10

上一篇下一篇

猜你喜欢

热点阅读