1. 程式人生 > >圖解 --樂觀鎖 悲觀鎖 可重入鎖 獨佔鎖 共享鎖 公平鎖 非公平鎖

圖解 --樂觀鎖 悲觀鎖 可重入鎖 獨佔鎖 共享鎖 公平鎖 非公平鎖

1.樂觀鎖--樂觀鎖是一種思想,它只解決對共享資源更新時的一致性問題,不解決讀取共享資源過程中,其他執行緒修改了共享資源導致讀取的是舊的資源的問題

一般正規化為:

private Node enq(final Node node) {
        for (;;) {
            Node t = tail;
            if (t == null) { // Must initialize
                if (compareAndSetHead(new Node()))
                    tail = head;
            } 
else { node.prev = t; if (compareAndSetTail(t, node)) { t.next = node; return t; } } } }

 

for(;;){
    更新期望共享資源;
    if(期望共享資源==現實共享資源){
    update();
    return
    }
}    

 

這種實現存在如下問題1):ABA問題----假如是連結串列結構,1執行緒操作期間,其他執行緒修改了A.next,1執行緒比較後自然以為是預期值,判斷true,繼續操作(解決辦法加入版本號標識,比較的不僅僅是A的值還有A的版本號)

          2):自旋導致cpu壓力

2.悲觀鎖--總是假設最壞的情況,每次去拿資料的時候都認為別人會修改,所以每次在拿資料的時候都會上鎖,這樣別人想拿這個資料就會阻塞直到它拿到鎖。應用場景可以抽象成如下圖

可重入鎖:獲取到外函式的鎖時,內部函式的鎖也獲取到了

獨佔鎖--每次只有一個執行緒能拿到鎖(比如synchronize 和reentrantLock)如上圖

 

共享鎖--多個執行緒拿到鎖(ReentrantReadWriteLock )如下圖,3個讀執行緒都獲取鎖,但是不允許讀寫執行緒和寫寫執行緒同時都持有鎖,理由很簡單。

公平鎖--後續等待執行緒是一個FIFO佇列,先排隊的先獲取鎖

非公平鎖--執行緒不排隊(預設,效率高)