1. 程式人生 > >(轉)Java atomic原子類的使用方法和原理(一)

(轉)Java atomic原子類的使用方法和原理(一)

trace over 本地 expec pda 安全性 cpp clas and

在講atomic原子類之前先看一個小例子:

public class UseAtomic {
   
   public static void main(String[] args) {
       AtomicInteger atomicInteger=new AtomicInteger();
       for(int i=0;i<10;i++){
            Thread t=new Thread(new AtomicTest(atomicInteger));
            t.start();
            try {
               t.join(0);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
               
       }
       System.out.println(atomicInteger.get());
   }
}
class AtomicTest implements Runnable{
   AtomicInteger atomicInteger;
   
   public AtomicTest(AtomicInteger atomicInteger){
       this.atomicInteger=atomicInteger;
   }
   @Override
   public void run() {
       atomicInteger.addAndGet(1);
       atomicInteger.addAndGet(2);
       atomicInteger.addAndGet(3);
       atomicInteger.addAndGet(4);
   }
   
}

最終的輸出結果為100,可見這個程序是線程安全的。如果把AtomicInteger換成變量i的話,那最終結果就不確定了。

打開AtomicInteger的源碼可以看到:

// setup to use Unsafe.compareAndSwapInt for updates
private static final Unsafe unsafe = Unsafe.getUnsafe();
private volatile int value;

volatile關鍵字用來保證內存的可見性(但不能保證線程安全性),線程讀的時候直接去主內存讀,寫操作完成的時候立即把數據刷新到主內存當中。

CAS簡要

/**
     * Atomically sets the value to the given updated value
     * if the current value {@code ==} the expected value.
     *
     * @param expect the expected value
     * @param update the new value
     * @return {@code true} if successful. False return indicates that
     * the actual value was not equal to the expected value.
     */
    public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

從註釋就可以看出:當線程寫數據的時候,先對內存中要操作的數據保留一份舊值,真正寫的時候,比較當前的值是否和舊值相同,如果相同,則進行寫操作。如果不同,說明在此期間值已經被修改過,則重新嘗試。
compareAndSet使用Unsafe調用native本地方法CAS(CompareAndSet)遞增數值。

CAS利用CPU調用底層指令實現。
兩種方式:總線加鎖或者緩存加鎖保證原子性。



作者:zxin1
鏈接:https://www.jianshu.com/p/a2f3c46d4783
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並註明出處。

(轉)Java atomic原子類的使用方法和原理(一)