/**
* 类说明:演示引用类型的原子操作类
*/
public class UseAtomicReference {
static AtomicReference<UserInfo> atomicUserRef;
public static void main(String[] args) {
UserInfo user = new UserInfo("Mark", 15);//要修改的实体的实例
atomicUserRef = new AtomicReference(user);
UserInfo updateUser = new UserInfo("Bill", 17);
boolean a = atomicUserRef.compareAndSet(user, updateUser);
System.out.println(a);
System.out.println(atomicUserRef.get());
System.out.println(user);
}
//定义一个实体类
static class UserInfo {
private volatile String name;
private int age;
public UserInfo(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return "UserInfo{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
}
注意:
atomicUserRef.compareAndSet(ユーザ、updateUser)は、オブジェクトが参照の元のパスを変更することであるが、値自体は変化しません
新しいAtomicReference(ユーザ);アトミック動作になるように、オブジェクトをカプセル化します
AtomicStampedReference
作ります
AtomicStampedReference <文字列> ASR =新しいAtomicStampedReference( "djy"、0);
ソースコード:
注意:
ここでは、非常に単純なバージョン管理を問題を解決することができ、いわゆるABAのAtomicStampedReferenceを見ることができます
ABAの問題解決
/**
* 类说明:演示带版本戳的原子操作类
*/
public class UseAtomicStampedReference {
static AtomicStampedReference<String> asr
= new AtomicStampedReference("djy", 0);
public static void main(String[] args) throws InterruptedException {
//拿到当前的版本号(旧)
final int oldStamp = asr.getStamp();
final String oldReference = asr.getReference();
System.out.println(oldReference + "============" + oldStamp);
Thread rightStampThread = new Thread(new Runnable() {
@Override
public void run() {
asr.compareAndSet(oldReference, "java", oldStamp, oldStamp + 1);
}
});
Thread errorStampThread = new Thread(new Runnable() {
@Override
public void run() {
String reference = asr.getReference();
int stamp = asr.getStamp();
asr.compareAndSet(reference, "C++", stamp, stamp + 1);
}
});
rightStampThread.start();
//让线程充分运行完毕
rightStampThread.join();
errorStampThread.start();
errorStampThread.join();
System.out.println(asr.getReference() + "============" + asr.getStamp());
}
}
AtomicMarkableReference
使用法と一貫AtomicStampedReference
違いAtomicMarkableReferenceとAtomicStampedReference?
AtomicStampedReference
コンストラクタinitialStamp(タイムスタンプ)が一意に内部構造に、参照変数を識別するために、インスタンスペアオブジェクト対オブジェクト記録タイムスタンプ情報と、タイムスタンプ、実際の使用において、へとしてINTを使用するオブジェクト参照タイムスタンプを繰り返した場合、表示された場合にのみ、(通常栽培で作られた)タイムスタンプを保証ABAの問題を。
AtomicStampedReferenceは、各参照変数を使用すると、ABAでCASの問題を解決できるように、このタイムスタンプをpair.stamp入れています。
/**
* Creates a new {@code AtomicStampedReference} with the given
* initial values.
*
* @param initialRef the initial reference
* @param initialStamp the initial stamp
*/
public AtomicStampedReference(V initialRef, int initialStamp) {
pair = Pair.of(initialRef, initialStamp);
}
AtomicMarkableReference
AtomicStampedReferenceのノウハウは、参照変数は、数回の途中で変更されました。時々 、私たちは何度か変更しましたが、単に心配参照変数を気にしない変化したか否か、そうそこAtomicMarkableReference。
唯一の違いはAtomicMarkableReferenceはもはやint型のアイデンティティリファレンスを使用していないが、ブール変数の使用は - 参照変数が変更されたかどうかを示します。
コンストラクタ
/**
* Creates a new {@code AtomicMarkableReference} with the given
* initial values.
*
* @param initialRef the initial reference
* @param initialMark the initial mark
*/
public AtomicMarkableReference(V initialRef, boolean initialMark) {
pair = Pair.of(initialRef, initialMark);
}