「N」個のスレッドが AtomicInteger 変数を CAS しようとしているとします。CAS が正確に 1 つのスレッドで成功しなければならないことが保証されていますか?
「N」個のスレッドすべてが試みに失敗する可能性はありますか?
「N」個のスレッドが AtomicInteger 変数を CAS しようとしているとします。CAS が正確に 1 つのスレッドで成功しなければならないことが保証されていますか?
「N」個のスレッドすべてが試みに失敗する可能性はありますか?
compareAndSet
ハードウェアによって実装されることを意図しているため、動作は実行している特定のハードウェアによって異なります。java.util.concurrent.atomic から:
このメソッド (クラスごとに引数の型が異なります) は、変数が現在 expectedValue を保持している場合、原子的に変数を updateValue に設定し、成功時に true を報告します。このパッケージのクラスには、値を取得して無条件に設定するメソッドと、以下で説明するより弱い条件付きアトミック更新操作の weakCompareAndSet も含まれています。
これらのメソッドの仕様により、最新のプロセッサで利用できる効率的なマシンレベルのアトミック命令を実装で使用できるようになります。ただし、一部のプラットフォームでは、サポートになんらかの形式の内部ロックが必要になる場合があります。したがって、メソッドが非ブロッキングであることが厳密に保証されているわけではありません。スレッドは、操作を実行する前に一時的にブロックする場合があります。
典型的なハードウェアを想定すると、基礎となるハードウェア命令に到達する最初のスレッドがアトミック CAS を実行し (正しい初期値があると仮定)、他のすべてのスレッドは失敗します。
基盤となるハードウェアが競合するすべてのスレッドの失敗を許容する場合、Java API には異なる動作を必要とするものは何もないように思われます。ただし、すべてのスレッドで失敗する可能性のある CAS は、ライブロックの状況や非決定論的な動作につながる可能性があるため、CAS を実装するハードウェアは、おそらく 1 つのスレッドが成功することを保証します。
同時実行関心リストで質問をして、次の回答を得たと言う価値があるかもしれません:
はい、AtomicX.compareAndSet に対して保証されています。
実際、「強い」CAS と「弱い」CAS には違いがあります。最初の CAS は誤って失敗することはありませんが、2 つ目の CAS は失敗する可能性があります。AtomicX.compareAndSet は「強力な」CAS です。AtomicX.weakCompareAndSet は「弱い」CAS の例であり、特定の理由がなくても、すべてのスレッドで誤って失敗する可能性があります。
強力な CAS を直接提供する代わりにLL/SCのみを備えたハードウェアでは、強力な CAS の内部実装には再試行ループが必要です。
したがって、Java レベルでは、強力な CAS は依然として強力ですが、ライブロック/競合/ハードウェア レベルからは、実際には再試行しています。