ReentrantLock獨佔鎖原始碼剖析

2021-10-01 01:53:28 字數 1378 閱讀 3350

在開始分析reentrantlock

獨佔鎖之前,我們先來簡單了解幾個概念:

悲觀鎖指對資料被外界修改持保守態度,認為資料很容易就會被其他執行緒修改,所以在資料被處理前先對資料進行加鎖,並在整個資料處理過程中,使資料處於鎖定狀態。例如synchronized。

樂觀鎖是相對悲觀鎖來說對,它認為資料在一般情況下不會造成衝突,所以在訪問資料前不會加排他鎖,而是在進行資料提交更新時,才會正式對資料衝突與否進行檢測。例如cas機制就是樂觀鎖對一種實現。

根據鎖只能被單個執行緒持有還是能被多個執行緒共同持有,鎖可以分為獨佔鎖和共享鎖:

獨佔鎖是一種悲觀鎖,保證任何時候只有乙個執行緒能得到鎖。

共享鎖則是一種樂觀鎖,允許多個執行緒同時進行讀操作。

根據執行緒獲取鎖的搶占機制,鎖可以分為公平鎖和非公平鎖:

公平鎖表示執行緒獲取鎖的順序是按照執行緒請求鎖的實踐早晚來決定的,也就是最早請求鎖的執行緒將最早獲取到鎖。

非公平鎖在執行時闖入,也就是先來不一定先得。

abstractqueuedsynchronizer抽象同步佇列簡稱aqs,它是實現同步器的基礎元件,鎖的底層就是使用aqs實現的。

aqs的使用依靠繼承來完成,子類通過繼承自aqs並實現所需的方法來管理同步狀態;從使用上來說,aqs可以分為兩種:獨佔和共享。

aqs維護了乙個fifo的雙向佇列和state狀態資訊,並且通過節點head和tail記錄隊首和隊尾的元素。

fifo佇列元素的型別為node。其中node中的thread變數用來存放當前節點對應的執行緒;node節點內部的shared用來標記該執行緒時獲取共享資源時被阻塞掛起後放入aqs佇列的;exclusive用來標記執行緒時獲取獨佔資源時掛起後放入aqs佇列的;waitstatus記錄當前執行緒等待狀態,可以為cancelled(執行緒被取消了)、signal(執行緒需要被喚醒)、condition(執行緒在條件佇列裡面等待)、propagate(釋放共享資源時需要通知其他節點);prev記錄當前節點的前驅節點;next記錄當前節點的後繼節點。

在aqs中維護了乙個單一的狀態資訊state,可以通過getstate、setstate、compareandsetstate函式修改其值。state的含義由子類去定義,自己只是提供了對state的維護。

reentrantlock獲取獨佔鎖的實現

reentrantlock是使用aqs實現的可重入的獨佔鎖,同時只能有乙個執行緒可以獲取該鎖,其他獲取該鎖的執行緒會被阻塞而被放入該鎖的aqs阻塞佇列裡面。其內部可根據構造引數來決定建立的是乙個公平鎖還是非公平鎖,預設是非公平鎖。

首先看下reentrantlock的類圖以便對它的實現有個大致了解。

ReentrantLock實現同步

reentrantlock 也可以實現synchronized方法 塊的同步效果。reentrantlock 實現同步 如下 1 新建乙個service類 public class myservice public static void methodb 2 新建乙個測試類 public class...

ReentrantLock之unlock方法分析

public void unlock public final boolean release int arg return false release 1 嘗試在當前鎖的鎖定計數 state 值上減1。成功返回true,否則返回false。當然在release 方法中不僅僅只是將state 1這麼...

ReentrantLock 原理分析

public void lock 這是lock的原始碼,呼叫的其實是sync這個物件的lock函式,而sync是reentrantlock內部類sync的乙個物件例項,他有兩種實現nonfairsync 非公平鎖 和fairsync 公平鎖 先看公平鎖的lock函式 final void lock ...