package org.springside.modules.metrics.metric;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import org.springside.modules.metrics.utils.Clock;
public abstract class CachedGauge<T extends Number> extends Gauge<T>{
public static Clock clock = Clock.DEFAULT;
private AtomicLong reloadAt = new AtomicLong(0);
private long timeoutNS = 0;
private volatile T value;
public CachedGauge() {
}
public CachedGauge(long timeout, TimeUnit timeoutUnit) {
this.reloadAt = new AtomicLong(0);
this.timeoutNS = timeoutUnit.toMillis(timeout);
}
@Override
public T getValue() {
if (shouldLoad()) {
this.value = loadValue();
}
return value;
}
private boolean shouldLoad() {
for (;;) {
final long time = clock.getCurrentTime();
final long current = reloadAt.get();
if (current > time) {
return false;
}
if (reloadAt.compareAndSet(current, time + timeoutNS)) {
return true;
}
}
}
//子类中实现
protected abstract T loadValue();
}