AQS.addWaiter
生活随笔
收集整理的這篇文章主要介紹了
AQS.addWaiter
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
當(dāng)tryAcquire方法獲取鎖失敗以后,則會(huì)先調(diào)用addWaiter將當(dāng)前線程封裝成Node.?
入?yún)ode表示當(dāng)前節(jié)點(diǎn)的狀態(tài),傳遞的參數(shù)是Node.EXCLUSIVE,表示獨(dú)占狀態(tài)。意味著重入鎖用到了AQS的獨(dú)占鎖功能
1. 將當(dāng)前線程封裝成Node
2. 當(dāng)前鏈表中的tail節(jié)點(diǎn)是否為空,如果不為空,則通過(guò)cas操作把當(dāng)前線程的node添加到AQS隊(duì)列?
3. 如果為空或者cas失敗,調(diào)用enq將節(jié)點(diǎn)添加到AQS隊(duì)列
private Node addWaiter(Node mode) { Node node = new Node(Thread.currentThread(), mode);//把當(dāng)前線程封裝為Node Node pred = tail; //tail是AQS中表示同比隊(duì)列隊(duì)尾的屬性,默認(rèn)是null if (pred != null) {//tail不為空的情況下,說(shuō)明隊(duì)列中存在節(jié)點(diǎn) node.prev = pred;//把當(dāng)前線程的Node的prev指向tail if (compareAndSetTail(pred, node)) {//通過(guò)cas把node加入到AQS隊(duì)列,也就是設(shè)置為tail pred.next = node;//設(shè)置成功以后,把原tail節(jié)點(diǎn)的next指向當(dāng)前node return node; } } enq(node);//tail=null,把node添加到同步隊(duì)列 return node; }enq
enq就是通過(guò)自旋操作把當(dāng)前節(jié)點(diǎn)加入到隊(duì)列中?
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; } } } }圖解分析
假設(shè)3個(gè)線程來(lái)爭(zhēng)搶鎖,那么截止到enq方法運(yùn)行結(jié)束之后,或者調(diào)用addwaiter方法結(jié)束后,AQS中的鏈表結(jié)構(gòu)圖
?
總結(jié)
以上是生活随笔為你收集整理的AQS.addWaiter的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ReentrantLock.nofair
- 下一篇: NofairSync.tryAcquir