質問
私はatomicreference.compardset()メソッドについていくつかの質問をしました。
現在の値==期待値の場合、指定された更新値に値をアトミックに設定します。
私が理解している限り、==
演算子は2つのオブジェクトのアドレスを比較していますが、この
private AtomicReference<AccessStatistics> stats =
new AtomicReference<AccessStatistics>(new AccessStatistics(0, 0));
public void incrementPageCount(boolean wasError) {
AccessStatistics prev, newValue;
do {
prev = stats.get();
int noPages = prev.getNoPages() + 1;
int noErrors = prev.getNoErrors;
if (wasError) {
noErrors++;
}
newValue = new AccessStatistics(noPages, noErrors);
} while (!stats.compareAndSet(prev, newValue));
}
.
このコードスニペットでは、AccessStatistics
でcompareAndSet()
のどのフィールドを比較するかについてどのようにJVMはどのようにしていますか。実際、Javaを考えると、この戦略全体が働いているのはどのように疑問に思いますか。
コメントをありがとう!
解決
CompareAndSet()でどのフィールドを比較するかをJVMにどのように比較するかをどのように知っていますか?
ではありません。オブジェクト内のフィールドを比較していません。それは、ドキュメントが言うものであるオブジェクトの reference を単に比較しています。それがAtomicReference
クラスのうちにどのように機能するかだけです。 javadocs 、==
メソッドではなくequals()
を使用します。
現在の値==期待値の場合、指定された更新値に値をアトミックに設定します。
Atomic*
クラスのすべてが同様の機能を持っています。それはあなたが別のスレッドがあなたの値を上書きしていない間は、値を原子的に設定することができます。 compareAndSet(...)
を使用すると、期待どおりに更新していることを確認するために現在のオブジェクト参照を指定する必要があります。
あなたのコードスニペットでは、それは不変のアクセス統計オブジェクトに追加しようとしています。そのため、現在の値を取得し、それに追加してから、新しい統計を参照に保存します。その時点の間に別のスレッドが at> at>統計を記憶している場合、compareAndSet
はfalseを返し、それがループして再試行します。これは、synchronized
ブロックを持たなくても競合条件を解決します。
他のヒント
JVMはフィールドをまったく比較しません。IT だけが同じ参照かどうか、メモリ内の同じポインタ、またはそれを呼び出したいものは何でも比較します。