這篇文章主要描述硬體同步原語,它是由電腦硬體提供的一組原子操作。 我們常見的原語操作有CAS和FAA兩種。在某些情景下,我們可以使用它來替代鎖,從而更加安全高效的操作數據。 ...
什麼是硬體同步原語?
硬體同步原語(Atomic Hardware Primitives)是由電腦硬體提供的一組原子操作。
我們常見的原語操作有CAS和FAA兩種。
CAS
Compare and Swap(CAS),字面意思是先比較,再計算。它的偽代碼如下。
<< atomic >>
function cas(p : pointer to int, old : int, new : int) returns bool {
if *p ≠ old {
return false
}
*p ← new
return true
}
它的輸入參數有三個:
- p:要修改的變數的指針
- old:舊值
- new:新值
返回值是一個布爾值,標識是否賦值成功。
FAA
Fetch and Add(FAA),它的含義是先獲取變數當前的值value,然後給變數p增加inc,最後返回變數p之前的值value。
它的偽代碼如下:
<< atomic >>
function faa(p : pointer to int, inc : int) returns int {
int value <- *location
*p <- value + inc
return value
}
上述兩段偽代碼,它們的特殊之處在於它們都是由電腦硬體,具體講就是CPU提供實現,可以保證操作的原子性。
因為原子操作具有不可分割性,也就不存在併發的問題,所以在某些情況下,原語可以用來替代鎖,實現一些安全又高效的併發操作。
CAS和FAA在各種編程語言中,都有相應的實現,可以直接使用,無論哪種編程語言,它們底層的實現是一樣的,效果也是一樣的。
Java中的操作原語
Java語言本身支持操作原語,Java中的CAS可以理解為樂觀鎖,java.util.concurrent.atomic包下麵的類已經實現了樂觀鎖,其中最常用的是AtomicInteger,可以將其看做實現了CAS操作的Integer。
下麵是使用AtomicInteger的示例代碼。
private static AtomicInteger count = new AtomicInteger(0);
public static void main(String[] args) {
for (int i = 0; i < 2; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10);
} catch (Exception e) {
e.printStackTrace();
}
//每個線程讓count自增100次
for (int i = 0; i < 100; i++) {
count.incrementAndGet();
}
}
}).start();
}
try{
Thread.sleep(2000);
}catch (Exception e){
e.printStackTrace();
}
System.out.println(count);
}
作者:李潘
出處:http://wing011203.cnblogs.com/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。