0

ドキュメントによると、AtomicReference.compareAndSet()メソッドについていくつか質問がありました。

現在の値==期待値の場合、原子的に値を指定された更新された値に設定します。

私が理解している限り、==オペレーターは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));
}

このコードスニペットでは、jvmはどのフィールドを?AccessStatisticsで比較するかをどのように認識しcompareAndSet()ますか?実際、Javaでオーバーライドがまったく許可されていない場合、この戦略全体がどのように機能するのか疑問に思っています==。コメントありがとうございます!

4

2 に答える 2

5

jvmは、compareAndSet()で比較されるAccessStatisticsのフィールドをどのように認識しますか?

そうではありません。オブジェクトのフィールドを比較していません。これは、ドキュメントに記載されているオブジェクトの参照を比較しているだけです。それがAtomicReferenceクラスの仕組みです。javadocsからおっしゃるように==、メソッドではなく使用しequals()ます。

現在の値==期待値の場合、原子的に値を指定された更新された値に設定します。

すべてのAtomic*クラスに同様の機能があります。別のスレッドが値を上書きしないようにしながら、アトミックに値を設定できます。compareAndSet(...)期待どおりに更新されていることを確認するには、現在のオブジェクト参照を指定する必要があります。

コードスニペットでは、不変のアクセス統計オブジェクトに追加しようとしています。したがって、現在の値を取得して追加し、新しい統計を参照に保存します。その間に別のスレッドが統計を保存したcompareAndSet場合、はfalseを返し、ループして再試行します。synchronizedこれにより、ブロックがなくても競合状態が解決されます。

于 2012-07-27T16:14:18.737 に答える
2

JVMはフィールドをまったく比較しません。それは、それが同じ参照であるか、メモリ内の同じポインタであるか、またはあなたがそれを呼び出したいものであるかどうかを比較するだけです。

于 2012-07-27T16:14:17.877 に答える