1. 程式人生 > >Java高並發程序設計(十)--無鎖

Java高並發程序設計(十)--無鎖

期望 spa 策略 edt sys .net () .html pac

鎖是一種悲觀策略,總是覺得會出問題,所以小心翼翼地操作。

無鎖是一種樂觀策略,總是假設不會出現問題,如果出現問題,那就重新操作。無鎖一般使用CAS作為策略。

比較交換CAS:

CAS算法包括三個參數:需要更新的變量,預期值,更新值。只有當需要更新的值等於預期值時,說明其他線程沒有對它進行操作,使需要更新值等於更新值。

在java.util.concurrent.atomic中,實現了很多無鎖的類型:

技術分享圖片

用AtomicInteger寫個小例子:

public class demo implements Runnable{
    static AtomicInteger ai=new AtomicInteger();
    
public static void main(String[] args) throws InterruptedException { ExecutorService es=Executors.newFixedThreadPool(10); for(int i=0;i<10;i++) { es.submit(new demo()); } Thread.sleep(1000); System.out.println(ai); } public void run() {
for(int i=0;i<100;i++) { ai.incrementAndGet(); } } }

沒有加鎖的情況下,輸出結果為1000,AtomicXX的操作都是具有原子性的,具體方法可以自己看API。

我們接下來看一下incrementAndGet()方法:

public final int incrementAndGet() {
        for (;;) {
            int current = get();
            int next = current + 1;
            
if (compareAndSet(current, next)) return next; } }

如上面對CAS算法的描述一樣,不斷嘗試直到成功,進入compareAndSet():

public final boolean compareAndSet(int expect, int update) {
    return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

調用了unsafe類的compareAndSwapInt,只需要知道他的大概意思就行,通過字段偏移量找到位置,通過期望值與待更新值的對比決定要不要更新。

Java高並發程序設計(十)--無鎖