美文网首页
store模块阅读6:ReferenceResource

store模块阅读6:ReferenceResource

作者: 赤子心_d709 | 来源:发表于2017-10-13 16:16 被阅读108次

    说明

    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

    相关文章

      网友评论

          本文标题:store模块阅读6:ReferenceResource

          本文链接:https://www.haomeiwen.com/subject/rhwoyxtx.html