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賦值為...