cas是無鎖優(yōu)化,或者叫自旋巴比。通過Atomic類來實現(xiàn)术奖。
由于一些常見的操作礁遵,加鎖的情況特別多,所以java提供了這些類采记,內部自帶了鎖佣耐,當然這些鎖不是由synchronized來實現(xiàn)的,而是通過cas的操作實現(xiàn)的唧龄。
public class study04 {
????public static void main(String[] args) {
????????study04 study =new study04();
? ? ? ? List threads =new ArrayList<>();
? ? ? ? for (int i=0; i <10; i++){
????????????threads.add(new Thread(study :: m, "thread-"+i));
? ? ? ? }
????????threads.forEach(o -> o.start());
? ? ? ? threads.forEach(o -> {
????????????try {
????????????????o.join();
? ? ? ? ? ? }catch (InterruptedException e) {
????????????????e.printStackTrace();
? ? ? ? ? ? }
????????});
? ? ? ? System.out.println(study.count);
? ? }
????AtomicIntegercount =new AtomicInteger(0);
? ? void m(){
????????for (int i =0; i <10000; i ++){
????????count.incrementAndGet();
? ? ????}
????}
}
count.incrementAndGet()的內部實現(xiàn):
public final int incrementAndGet() {
????return unsafe.getAndAddInt(this, valueOffset, 1) +1;
}
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;
}
compareAndSwapInt:
cas(V, Expected, NewValue)
? ? if V == Expected
? ? ? ? V = NewValue
? ? ? ? otherwise try again or fail
V是要修改的值兼砖,Expected是期望值,NewValue是新值,如果要修改的值等于期望值讽挟,那么代表沒有其他線程修改過它懒叛,可以設定新值,否則代表有其他線程修改過值耽梅,那么cas要重新嘗試讀取期望值薛窥。cas操作是cpu原語級的,中間不允許被打斷眼姐,是原子性的诅迷。
CAS修改的如果是對象會導致ABA問題。線程A發(fā)現(xiàn)對象(Expected)的引用還是原來的引用众旗,就允許修改罢杉,但其實該對象可能已經(jīng)被線程B修改過值并重新引用到原來的對象上,線程A無法發(fā)現(xiàn)贡歧。要解決ABA問題需要引入版本號滩租,compare的時候連版本號一起比較。
CAS是通過Unsafe這個類來實現(xiàn)的利朵。