为什么在释放锁的时候是从 tail 进行扫描
生活随笔
收集整理的這篇文章主要介紹了
为什么在释放锁的时候是从 tail 进行扫描
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
回到enq那個方法、在標(biāo)注為紅色部分的代碼來看一個新的節(jié)點(diǎn)是如何加入到鏈表中的。
1. 將新的節(jié)點(diǎn)的prev指向tail?
2. 通過cas將tail設(shè)置為新的節(jié)點(diǎn),因為cas是原子操作所以能夠保證線程安全性
3. t.next=node;設(shè)置原tail的next節(jié)點(diǎn)指向新的節(jié)點(diǎn)
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; } } } }在cas操作之后,t.next=node操作之前。?存在其他線程調(diào)用unlock方法從head開始往后遍歷,由于t.next=node還沒執(zhí)行意味著鏈表的關(guān)系還沒有建立完整。就會導(dǎo)致遍歷到t節(jié)點(diǎn)的時候被中斷。所以從后往前遍歷,一定不會存在這個問題。
圖解分析
通過鎖的釋放,原本的結(jié)構(gòu)就發(fā)生了一些變化。head節(jié)點(diǎn)的waitStatus變成了0,?ThreadB被喚醒
?
總結(jié)
以上是生活随笔為你收集整理的为什么在释放锁的时候是从 tail 进行扫描的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 锁的释放流程-unparkSuccess
- 下一篇: 原本挂起的线程继续执行