CAS の中心となるアイデアとその基礎となる実装


★1.CASとは何ですか?

CAS はコンペア アンド スワップの略で、並列アルゴリズムを実装するときに一般的に使用される手法ですメモリ値が期待値と等しい場合は更新し、それ以外の場合は何もしないか、再度開始します

CAS の基本的な実装: ハードウェアによって実装され、ハードウェアのアトミック性に依存します。CASは CPU のアトミック命令( cmpxchg 命令) であり、いわゆるデータの不整合の問題は発生しません

やり直す ==>自旋

CAS はオプティミスティック ロックに似ています。他の人が変更していないと楽観的に信じます。値が期待値のままであれば、変更されます。そうでない場合は、何も実行しないか、最初からやり直します。


★2. CAS適用例

  • アトミック操作クラス(整数アトミック操作クラスのcompareAndSetメソッドなど)
  • 私のブログ プロジェクトでは、記事のビュー数を更新するときに、現在のメモリ内の記事のビュー数と予想されるデータベース内の記事のビュー数を比較し、同じであれば 1 を加算し、そうでない場合は何も行いません。



3. アトミッククラス

アトミッククラス ==> 基本的な考え方/動作原理 CAS ==> Unsafe クラスの CPU プリミティブレベルのアセンブリ動作

  • CAS はハードウェアによって実装され、ハードウェアのアトミック性に依存しており、 CPUのアトミックな命令( cmpxchg 命令) であるため、いわゆるデータの不整合の問題は発生しません

    Unsafe によって提供される CAS メソッド (compareAndSwapXXX など) の基礎となる実装は、CPU 命令 cmpxchg です。


■ AtomicInteger クラスは主にCAS + volatileメソッドとネイティブ メソッドを使用してアトミックな操作を保証するため、同期の高いオーバーヘッドが回避され、実行効率が大幅に向上します。

new AtomicInteger().compareAndSet(0, 1);

// 底层实现
public final int getAndAdd(int delta) {
    
    
 return unsafe.getAndAddInt(this, valueOffset, delta);
}
public final boolean compareAndSet(int expect, int update) {
    
    
 return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}



new AtomicInteger().getAndAdd(1);//获取到当前值并加1
// 底层实现
public final int getAndAdd(int delta) {
    
    
return unsafe.getAndAddInt(this, valueOffset, delta);
}
public final int getAndAddInt(Object var1, long var2, int var4) {
    
    
int var5;
do {
    
    
   var5 = this.getIntVolatile(var1, var2);
} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
return var5;
}

仕事ではUnsafeクラスの使用は非推奨 クラス名を見ると「安全ではない」ことがわかります!



4. 安全でないクラス

  • 是CAS的核心类
  • できる像C的指针一样直接操作内存
  • Unsafe类中的所有方法都是native修饰的Unsafe类中的方法都可以直接调用操作系统底层资源去执行相应任务
//原子类
public final int getAndIncrement() {
    
    
     return unsafe.getAndAddInt(this, valueOffset, 1);
}

private volatile int value;

Unsafe はメモリオフセット アドレスに基づいてデータを取得するため、変数valueOffset はメモリ内の変数 value のオフセット アドレスを表します

複数のスレッド間でメモリの可視性を確保するために、変数値は volatile で変更されます。毎回取得される値が最新となります。



5. CASによる問題

  • サイクル時間が長く、ループが無限になる可能性があり、オーバーヘッドが高くなります。
  • ABAに関する質問
    • ABA 問題の解決:バージョン番号付きの AtomicStampedReference




この記事が役に立った場合は、忘れずに Yile に「いいね!」を押してください。ありがとうございます。

おすすめ

転載: blog.csdn.net/weixin_45630258/article/details/127043184