1.實(shí)現(xiàn)原理
AQS,隊(duì)列同步器。通過volitile變量state和CAS實(shí)現(xiàn)的一個(gè)雙端隊(duì)列,子類需要重寫tryAcquire方法
AQS獲取鎖的步驟
- A嘗試獲取鎖
- 如果失敗,則將A封裝成一個(gè)Node,嘗試通過CAS將其放入隊(duì)列尾部
- 放入隊(duì)列尾部的時(shí)候也去嘗試獲取鎖,如果還沒有成功,加入隊(duì)列尾部。
- 如果該節(jié)點(diǎn)的pre是頭節(jié)點(diǎn),則其自旋,不斷的去獲取鎖;
- 如果pre不是頭結(jié)點(diǎn),則通過LockSupport.park() 方法將其阻塞
2.RetreentLock
可重入鎖,實(shí)現(xiàn)了FairLock和UnFairLock,默認(rèn)是UnFairLock;
公平鎖的獲取,先看有沒有線程占有鎖。AQS隊(duì)列自旋的時(shí)候要去看pre節(jié)點(diǎn)是不是頭結(jié)點(diǎn);如果是頭結(jié)點(diǎn),看獲取鎖的是否是當(dāng)前線程,如果是,則獲取鎖,如果不是,獲取失敗。
非公平鎖不會(huì)去看頭節(jié)點(diǎn)是否是頭結(jié)點(diǎn)。先看有沒有線程獲取鎖,在看獲取鎖的是不是當(dāng)前線程。
非公平鎖效率高,可重入鎖效率高
3.ReentrantReadWriteLock
讀寫鎖氛圍讀鎖和寫鎖。
3.1實(shí)現(xiàn)
一個(gè)32位的數(shù)字,高16位是寫鎖,低16位是讀鎖
3.2 寫鎖
寫鎖是獨(dú)占式的可重入鎖,
當(dāng)一個(gè)線程獲取鎖,如果有讀鎖或者寫鎖占用著,則獲取失敗;
3.3讀鎖
讀鎖時(shí)可以共享的可重入鎖,
當(dāng)一個(gè)線程A獲取讀鎖,
如果當(dāng)前其他線程B占用著寫鎖,則,獲取失敗;如果B占用讀鎖,則獲取成功;
如果當(dāng)前線程占用寫鎖,也能獲取成功;
3.4鎖降級(jí)
是指一個(gè)線程將當(dāng)前的寫鎖降級(jí)成讀鎖,但是不支持升級(jí);
降級(jí)的過程:? 獲取寫鎖---獲取讀鎖---釋放寫鎖;
不是在釋放寫鎖之后獲取讀鎖,是因?yàn)榉乐蛊渌€程獲取資源的鎖后,修改了資源,該線程發(fā)生了幻讀。
4.Condition對象
每一個(gè)Lock中都有一個(gè)ConditionObject對象,其實(shí)是封裝在AQS里面。SYNC繼承了AQS,F(xiàn)airSYNC和UnFairSYNC都繼承了SYNC,SYNC,F(xiàn)airSYNC和UnFairSYNC都是RetreentLock的內(nèi)部類。
獲取Condition必須之前獲取了鎖,每一個(gè)Condition有自己的等待隊(duì)列,當(dāng)調(diào)用LockSupport.park()進(jìn)入等待隊(duì)列,LockSupport.unpark()從等待隊(duì)列中出來,進(jìn)入AQS的同步隊(duì)列。