首先給出乙個併發程式設計時,對於計數器進行累加時有問題的程式:
public class countexample1 catch (interruptedexception e)
countdownlatch.countdown();
});}
countdownlatch.await();
executorservice.shutdown();
log.info("count:{}", count);
}private static void add()
}
上述**,本意是執行之後,count的值為5000,實際上每次執行的結果都小於5000。
改進:將上述的int改為atomicinteger,如下:
public class countexample2 catch (interruptedexception e)
countdownlatch.countdown();
});}
countdownlatch.await();
executorservice.shutdown();
log.info("count:{}", count);
}private static void add()
}
刪除**中每次執行的結果都是5000,與我們預期的一致。
那麼atomicinteger的實現原理是什麼呢?
檢視count.incrementandget()函式的實現,如下:
public final int incrementandget()
這個unsafe類提供的getandaddint(object var1, long var2, int var4),檢視該原始碼為:
public final int getandaddint(object var1, long var2, int var4) while(!this.compareandswapint(var1, var2, var5, var5 + var4));
return var5;
}
分析上述方法:
var5通過獲取本地中的變數(其實應該取的是
主存的值),然後比較當前的var2的值與本地變數var5是否相等,如果不相等則重複判斷,直到相等才執行增加操作。這樣就保證資料的一致性。這個也叫做cms。
AtomicInteger原始碼分析
最常需要解決的問題是i 這個語義在多執行緒中是不安全的。雖然從語法上看上去是乙個操作,實際上分為了三步。取出i的值,i 1,將i 1的計算結果賦值給i。假設i的初始值為5,一種不安全的情況如下 1 2345 6執行緒1 i 5 i 1 6 i 6 執行緒2i 5 i 1 6 i 6 也就是說兩個執行...
AtomicInteger原始碼解析
1.為什麼要使用atomicinteger 使用atomicinteger的原因來自於多執行緒併發情況下帶來的原子性問題 注 所謂原子操作是指不會被 執行緒排程 機制打斷的操作 這種操作一旦開始,就一直執行到結束,中間不會有任何 context switch 切 換到另乙個執行緒 舉乙個例子,比如說...
AtomicInteger原始碼解析
atomicinteger,由於儲存的值的value是volatile型別所有具有執行緒可見性。通過cas比較交換進行自增,或者更新值具有原子性。所以atomicinteger是執行緒安全的具有類鎖一樣的執行緒安全性。具體參見下面原始碼解析 private static final unsafe u...