無鎖之Atomic大雜燴


Atomic包共有12個類,可以分為四大類,基本類型的原子更新,數組的原子更新,引用的原子更新,volatile字段的原子更新。Atomic包里的類基本都是使用Unsafe實現的包裝類。

基本類型的原子更新

AtomicBoolean
AtomicInteger
AtomicLong

數組的原子更新

AtomicIntegerArray
AtomicLongArray
AtomicReferenceArray

對象的原子更新

AtomicReference
AtomicMarkableReference
AtomicStampedReference // 原子更新帶有版本號的引用類型,用於解決CAS時,可能出現的ABA問題

volatile字段的原子更新

AtomicIntegerFieldUpdater
AtomicLongFieldUpdater
AtomicReferenceFieldUpdater

AtomicInteger的主要方法

  • compareAndSet(int expect, int update) // 如果當前值 ==預期值,則以原子方式將該值設置為給定的更新值
  • addAndGet(int delta) // 以原子方式將給定值與當前值相加,返回新值
  • decrementAndGet() // 以原子方式將當前值減 1,返回新值
  • incrementAndGet() //以原子方式將當前值減 1,返回新值
  • set(int newValue) // 設置為給定值 get() //獲取當前值

  • getAndAdd(int delta) // 以原子方式將給定值與當前值相加,返回舊值

  • getAndDecrement() //以原子方式將當前值減 1,返回舊值
  • getAndIncrement() // 以原子方式將當前值減 1,返回舊值
  • getAndSet(int newValue) // 以原子方式設置為給定值,並返回舊值

栗子

基本類型的原子更新

    static AtomicBoolean atomicBoolean=new AtomicBoolean(false);
static AtomicInteger atomicInteger=new AtomicInteger(1);
static AtomicLong atomicLong=new AtomicLong(1L);

public static void main(String[] args) {
atomicBoolean.set(true);
atomicInteger.incrementAndGet();
atomicLong.decrementAndGet();
}

數組的原子更新

    static int[] intArray=new int[]{1,2};
static long[] longArray=new long[]{1L,2L};
static String[] stringArray=new String[]{"1","2"};

static AtomicIntegerArray atomicIntegerArray=new AtomicIntegerArray(intArray);
static AtomicLongArray atomicLongArray=new AtomicLongArray(longArray);
static AtomicReferenceArray atomicReferenceArray=new AtomicReferenceArray(stringArray);

public static void main(String[] args) {
atomicIntegerArray.set(0, 2);
atomicLongArray.set(0, 2L);
atomicReferenceArray.set(0, "2");
}

對象的原子更新

    static AtomicReference atomicReference=new AtomicReference();
static String ref1="aaa";
static AtomicMarkableReference atomicMarkableReference=new AtomicMarkableReference<String>(ref1,false);

static Integer ref2=111;
static AtomicStampedReference atomicStampedReference=new AtomicStampedReference<Integer>(ref2, 0);

public static void main(String[] args) {
Demo demo1=new Demo("aaa","111");
Demo demo2=new Demo("bbb","222");
atomicReference.set(demo1);
atomicReference.compareAndSet(demo1,demo2);

if(atomicMarkableReference.isMarked()!=true){
atomicMarkableReference.set("bbb", true);
};

if(atomicStampedReference.getStamp()==0){
atomicStampedReference.set(new Integer("222"), 1);
}
}

static class Demo{
public Demo(String name,String address){
this.name=name;
this.address=address;
}
private String name;
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}

volatile字段的原子更新

    static AtomicIntegerFieldUpdater atomicIntegerFieldUpdater=AtomicIntegerFieldUpdater.newUpdater(Demo.class, "v1");
static AtomicLongFieldUpdater atomicLongFieldUpdater=AtomicLongFieldUpdater.newUpdater(Demo.class, "v2");
static AtomicReferenceFieldUpdater atomicReferenceFieldUpdater=AtomicReferenceFieldUpdater.newUpdater(Demo.class, String.class, "v3");

public static void main(String[] args) {
Demo demo1=new Demo();
atomicIntegerFieldUpdater.incrementAndGet(demo1);
atomicLongFieldUpdater.incrementAndGet(demo1);
atomicReferenceFieldUpdater.set(demo1, "aaa");
System.out.println(demo1.v1);
System.out.println(demo1.v2);
System.out.println(demo1.v3);
}

static class Demo{
public volatile int v1; //不能用Integer
public volatile long v2; //不能用Long
public volatile String v3;
}

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com