通常、読み取り中は読み取りロックで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()にあり、いくつかの余分なカウントを「カウントする可能性があります」。しかし、ほとんどの場合、おそらく正しい値であり、場合によっては1つの余分なカウントがあります。しかし、私はそれをもっと正確にしたいと思っています。
トリックは次のとおりです。
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();
}
}
私の質問は、私はもっとうまくやれるでしょうか?
ソルト:(キャスト)の問題については知っています。count.get()を複数回呼び出すなど、パフォーマンスを向上させるために回避できますが、コードをあまり乱雑にしたくありませんでした。