まず、CASは何ですか?
CAS、英語名:コンペア・アンド・スワップは、交換を比較します。主のAtomicIntegerクラスで使用される、基本的な原理は、現実と期待値と同じで、修正が成功し、そうでない場合は、変更が失敗しました。安全でない下地のコールタイプは、この方法は、直接基礎となるJavaシステムにアクセスできないのでCAS危険コアクラスは、直接操作することができ、特定のメモリのためにそのようなデータに基づいて、ローカル(ネイティブ)法、バックドア危険等価でアクセスする必要があります。メソッドは、JavaクラスCAS危険な操作で実行依存しているため、操作の内部ポインタの方法として、パケットタイプ危険sun.misc存在は、Cと同様に、動作メモリを指示することができます。揮発性の変数の値は、複数のスレッド間でのメモリの視認性を確保するために修正ここ。CASは、安全でないクラスによって、CPUの並行処理プリミティブで、JVMは原子性を確保するために、CAS組立説明書から私たちを助けることであるしましょう。そのため、スレッドの安全性を確保するためにCASを使用します。
主のcompareAndSet(期待INT、INT更新)法により、その使用は、基礎となるには、次のとおりです。
変数のアドレス値、期待値、更新された値の現在値を割り当てられ、
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
安全でないクラスcompareAndSwapInt
public final native boolean compareAndSwapInt(Object var1, long var2,
int var4, int var5);
方法可変増加
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;
}
異なる場合は、値の結果の増加と期待値を見ることができたときに、それが循環してきました。
二、CASの欠点
CASは、スレッドセーフを保証しますが、ロックされていない、高効率によって複雑にすることができますので、それは完璧ではないですか?完璧な事は、その欠点は何ですか、それはないが、ありませんか?次のような欠点があります
CAS短所:
長いサイクル時間、大きなオーバーヘッドが
唯一の共有変数の動作を保証することができます
三、ABAの問題?
CASは、スレッドセーフを保証しますが、ロックされていない、高効率によって複雑にすることができますので、それは完璧ではないですか?完璧な事は、その欠点は何ですか、それはないが、ありませんか?ABAは、メインメモリ、スレッドはメインメモリにメインメモリに書き込ま戻った後、修正100と101を持って、そして100、Bのスレッドが開始されたときに同じことが再び101に改訂されたとき、ABAの問題と呼ばれる問題は、例えば、あるあります100に入るが、今Bの値はまだ100です見つける、100の値が変更されていないが、それは真実ではない、100が変更されたと考えられています。(また、二回改訂!!!)これは、ABAの問題と呼ばれています。
第四に、どのようにABAの問題を解決するには?
修正版、AtomicStampedReferenceで、クラスのメソッドを使用してのcompareAndSetのバージョン番号を定義することができ、あなたが変更するたびに、設定されたバージョン番号もそう、彼らはクラスでは、バージョン番号によって変更されたかどうかを識別できるように変更されたので、以下のクラスであります基礎となるソースコード
public AtomicStampedReference(V initialRef, int initialStamp) {
pair = Pair.of(initialRef, initialStamp);
}
private static class Pair<T> {
final T reference;
final int stamp;
private Pair(T reference, int stamp) {
this.reference = reference;
this.stamp = stamp;
}
static <T> Pair<T> of(T reference, int stamp) {
return new Pair<T>(reference, stamp);
}
}
public boolean compareAndSet(V expectedReference,
V newReference,
int expectedStamp,
int newStamp) {
Pair<V> current = pair;
return
expectedReference == current.reference &&
expectedStamp == current.stamp &&
((newReference == current.reference &&
newStamp == current.stamp) ||
casPair(current, Pair.of(newReference, newStamp)));
}
ご質問がある、と指摘してください!!!