通常我們在讀取時使用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()等可以避免出現更好的性能,但是不想混淆代碼太多。
你知道爲什麼它有多個併發讀取,同時防止併發寫入,但不是相反嗎?我不認爲你這樣做。 –
@MattBall他希望*平均值*是準確的,但要計算它需要同步兩個*原子。如果在兩個gets()之間發生寫操作,calc將會出錯 - 這是他的問題 – Bohemian
您應該將read.unlock()放在finally塊中... – breezee