说明
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是不会出现的.
网友评论