CLH鎖的原理和實現

2021-09-24 04:55:42 字數 1719 閱讀 7690

public class clhlockv2 

/*** 隱式鍊錶的尾節點

*/private volatile clhnodev2 tail = null;

/*** 儲存當前執行緒對應的隱式節點

*/private threadlocalcurrentthreadnode = new threadlocal<>();

/*** 原子更新器

** 字段引數說明:

* 包含該字段的物件的類

* 將被更新的物件的類

* 將被更新的字段的名稱

** 作用:保證更改引數為原子操作。getandset方法使得節點類clhnodev2之間有乙個隱式的前驅指標。後面詳細說明。

*/private static final atomicreferencefieldupdater updater = atomicreferencefieldupdater

.newupdater(

clhlockv2.class,

clhnodev2.class,

"tail");

/*** 加鎖

*/public void lock()

//通過getandset方法實現了隱式鍊錶,(各個節點之間好像有乙個前驅指標指向前乙個節點,其實沒有),

//它是通過getandset這個方法的返回值去獲取當前clhlockv2的tail以前指向的節點,也就是當前尾節點的前乙個節點。

//比如現在尾節點是a,現在呼叫方法getandset(this,b);現在tail指向b,方法返回a,如果a不為空的話就去空轉,

// 直到a節點的狀態變更(變更在unlock中)。

//這就是隱式鍊錶形成的原因

//所以這個演算法的鎖是在它的前乙個節點空轉。

clhnodev2 predecessor = (clhnodev2) updater.getandset(this, cnode);

if (predecessor != null)

}// 沒有前驅節點表示可以直接獲取到鎖,由於預設獲取鎖狀態為true,此時可以什麼操作都不執行

// 能夠執行到這裡表示已經成功獲取到了鎖

}/**

* clh釋放鎖

*/public void unlock()

// 移除執行緒和節點的繫結關係

currentthreadnode.remove();

//cas,比較clhlockv2的tail欄位指向的節點和當前執行緒繫結的節點是不是乙個,如果是則說明所有節點都已經解鎖,設定尾節點為null,不需要改變節點狀態了。

//如果不是說明還有其他節點,需要將當前節點的狀態改變,讓其他執行緒停止空轉,執行任務。

if (!updater.compareandset(this, cnode, null))

}/**

* 用例

** @param args

*/public static void main(string args)

}private static runnable generatetask(final clhlockv2 lock, final string taskid) catch (exception e)

system.out.println(string.format("thread %s completed", taskid));

lock.unlock();};}

}

AQS共享鎖的實現原理

前面的文章lock的實現中分析了aqs獨佔鎖的實現原理,那麼接下來就分析下aqs是如何實現共享鎖的。共享鎖的介紹 共享鎖 同一時刻有多個執行緒能夠獲取到同步狀態。那麼它是如何做到讓多個執行緒獲取到同步狀態呢?來看一下獲取共享鎖的過程 1.執行緒呼叫aqs的acquireshared 申請獲取鎖 可有...

鎖隔離級別實現原理

1 讀未提交,事務在讀資料時並不加鎖,事務在寫資料時加行級共享鎖。2 讀已提交,事務對當前被讀取的資料加行級共享鎖 當讀到時才加鎖 一旦讀完,立即釋放該行級共享鎖 事務在更新某資料的瞬間,必須先加行級排他鎖,直到事務結束才釋放。3 可重複讀,事務在讀取某資料瞬間 開始讀取的瞬間 必須先對其加行級共享...

go 互斥鎖實現原理

目錄2.加解鎖過程 3.自旋過程 4.mutex模式 5.woken狀態 6.為什麼重複解鎖要panic go中通過mutex來實現對互斥資源的鎖定 go type mutex struce下圖展示了mutex的記憶體布局 協程之間搶鎖的過程實際上是給locked賦值1的過程,能給locked賦值為...