通常我们在读取时使用带有读锁的ReadWriteLocks,在写入时使用写锁。但是我认为反向使用的奇特案例会有所帮助。但希望你们能告诉我一个更好的方法。
这就是我想要的。将有很多写入,但读取量很少。示例是请求延迟的平均计算器,例如。
几乎将其视为伪代码。
metric.addValue(latency); // Called a lot.
metric.getAverage(); // Called sparingly.
我们可以做到以下几点:
addValue(value) {
atomicCount.increment();
atomicSum.increment(value);
}
getAverage() {
return atomicCount.get() != 0 ? atomicSum.get() / atomicCount.get() : 0.0;
}
问题出在 getAverage() 中,我们“可能”计算了一些额外的计数。但大多数情况下可能是正确的值,有时还有一个额外的计数。但我只是想让它更精确。
这是诀窍:
ReadWriteLock rw = /* write preference, or a fair lock. */;
Lock read = rw.readLock();
Lock write = rw.writeLock();
addValue(value) {
read.lock(); // Using read lock when mutating.
try {
atomicCount.increment();
atomicSum.increment(value);
} finally {
read.unlock();
}
}
getAverage() {
write.lock(); // Using write lock when reading.
try {
return atomicCount.get() != 0 ? atomicSum.get() / atomicCount.get() : 0.0;
} finally {
write.unlock();
}
}
我的问题是,我能做得更好吗?
Salt:我知道 (cast) 问题,并且可以避免多次调用 count.get() 等以获得更好的性能,但不想让代码过于混乱。