★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 に「いいね!」を押してください。ありがとうございます。