ホームページ >Java >&#&チュートリアル >JavaでCASを適用する方法
CAS (比較および交換)、比較および交換。マルチスレッド並列状況でロックを使用することによって引き起こされるパフォーマンス損失を解決できるメカニズム。CAS 操作には、メモリ位置 (V)、期待される元の値 (A)、および新しい値 (B) の 3 つのオペランドが含まれます。メモリ位置の値が予想される元の値と一致する場合、プロセッサはその位置を新しい値に自動的に更新します。それ以外の場合、プロセッサは何も行いません。スレッドはメイン メモリから num 値を取得し、num に対して操作します。値を書き込むとき、スレッドは取得した最初の num 値とメイン メモリ内の num 値を比較します。それらが等しい場合、変更された値は num になります。それらが等しくない場合、成功するまで比較がループされます。
volatile キーワードはシェア変数を変更するときによく使用されますが、volatile 値には可視性があり、命令の再実行 (順序性) が禁止され、アトミック性は保証されません。シングルスレッドでは問題ありませんが、マルチスレッドではさまざまな問題が発生し、現場の不安が生じます。したがって、CAS は jdk1.5 以降に作成され、オンサイト操作のアトミック性を確保するために CPU プリミティブ (分割不可、継続的、中断なし) を使用します。
JDK1.5 の新しい java.util.concurrent(JUC) は CAS 上に構築されています。同期ロック メカニズムと比較すると、CAS はノンブロッキング アルゴリズムの一般的な実装です。したがって、JUC のパフォーマンスは大幅に向上しました。
たとえば、AtomicInteger クラス AtomicInteger はスレッドセーフです。ソース コードは次のとおりです。
Enter安全ではないため、自己ループ処理を参照してください。ここでの自己ループとは、期待される元の値が元の値と一致しない場合に、リサイクルして元の値を取得し、新しい値が得られるまで CAS プロセスを実行すると判断することです。正常に割り当てることができます。
cas はオプティミスティック ロックのアイデアであり、ノンブロッキングの軽量オプティミスティック ロックです。ノンブロッキングとは、スレッドの障害や一時停止が影響を与えるアルゴリズムに影響を与えないことを意味します。他のスレッドの失敗またはハング。
サイクル時間が長く、オーバーヘッドが大きく、CPU リソースを消費します。スピン ロックが長時間失敗すると、CPU に多大なオーバーヘッドが生じます。 JVM がプロセッサーが提供する一時停止命令をサポートできれば、効率はある程度改善されます。一時停止命令には 2 つの機能があります。1 つは、CPU が実行しないようにパイプライン実行命令を遅延 (デパイプライン) することです。実行リソースを大量に消費します。遅延の量は実装によって異なり、一部のプロセッサでは遅延がゼロになります。第二に、ループを終了するときにメモリ順序違反によって引き起こされる CPU パイプラインのフラッシュを回避できるため、CPU の実行効率が向上します。
共有変数に対するアトミック操作のみが保証されます。共有変数で操作を実行する場合、循環 CAS を使用してアトミックな操作を保証できます。ただし、複数の共有変数で操作する場合、循環 CAS は操作のアトミック性を保証できません。この場合、ロックを使用するか、 a 秘訣は、複数のシェア変数を 1 つのシェア変数にマージして操作することです。たとえば、2 つの共有変数 i=2、j=a があり、ij=2a をマージし、CAS を使用して ij を操作するとします。 Java 1.5 以降、JDK では参照オブジェクト間のアトミック性を確保するための AtomicReference クラスが提供され、1 つのオブジェクトに複数の変数を入れて CAS 操作を実行できます。
ABA問題
ABA問題の解き方(結末を考慮した値であれば過程は考慮せず無視して構いません)
バージョン番号を追加
AtomicStampedReference
アトミックで提供されますJava1.5から始まるJDKのパッケージ ABA問題を解決するクラスAtomicStampedReferenceが作成されています。このクラスの CompareAndSet メソッドは、まず現在の参照が予期される参照と等しいかどうか、および現在のフラグが予期されるフラグと等しいかどうかを確認します。すべてが等しい場合は、参照とフラグの値をアトミックに設定します。指定された更新値。
スレッドの数が少なく、待ち時間が短い場合は、スピン ロックを使用して CAS がロックの取得を試みることができます。これは同期よりも効率的です。
スレッド数が多く待ち時間が長いため、スピンロックの使用は推奨されず、CPU を大量に消費します
以上がJavaでCASを適用する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。