聊聊高併發(十一)實現幾種自旋鎖(五)
給出了限時有界佇列鎖的lock和unlock實現。這篇給出trylock的實現
trylock比lock略微複雜一點。要處理超時的情況。超時有幾種情況:
1. 第一步在等待佇列還沒有獲得節點的時候超時,直接返回false就可以
2. 第二步在等待佇列已經獲得節點可是還沒有增加工作佇列時超時,把節點狀態能夠直接改成free給興許執行緒使用,然後返回false就可以
3. 第三步在前乙個節點的狀態上自旋時超時,將節點的prenode設定成前乙個節點,然後將節點狀態改成aborted。然後返回就可以。興許節點在該節點的狀態自旋,當發現這個前驅節點已經是aborted了。興許節點就把前驅節點的prenode上自旋,然後把這個節點狀態改成free,給其它執行緒使用。
qnode的prenode欄位僅僅有當在工作佇列中超時的時候才會被設定。也僅僅被興許節點使用一次,並且該域總是先設定,再使用。所以也不須要顯式地在其它地方清空該域。
public boolean trylock(long time, timeunit unit)throws interruptedexception
if (tail.compareandset(tailnode, prenode, currentstamp[0],
currentstamp[0] + 1)) }}
if (node.state.compareandset(state.free, state.waiting))
try catch (interruptedexception e)
if (timeout(expectedtime, system.currenttimemillis()))
} // 第二步增加佇列
int currentstamp = new int[1];
qnode pretailnode = null;
do } // 假設沒增加佇列,就一直自旋
while (!tail.compareandset(pretailnode, node, currentstamp[0],
currentstamp[0] + 1));
// 第三步在前乙個節點自旋,假設前乙個節點為null。證明是第乙個增加佇列的節點
if (pretailnode != null)
if (timeout(expectedtime, system.currenttimemillis()))
s = pretailnode.state.get();
}// 設定前乙個節點的狀態為free,能夠被其它執行緒使用
pretailnode.state.set(state.free);
} // 將執行緒的mynode指向獲得鎖的node
mynode.set(node);
return true;
}
高併發下的redis加鎖的幾種實現方式
redis加鎖分類 redis能用的的加鎖命令分表是incr setnx set 第一種鎖命令incr 這種加鎖的思路是,key 不存在,那麼 key 的值會先被初始化為 0 然後再執行 incr 操作進行加一。然後其它使用者在執行 incr 操作進行加一時,如果返回的數大於 1 說明這個鎖正在被使...
微服務 Redis高併發下分布式鎖實現
傳統的軟體公司,依然堅持用著三層架構,單體的應用程式可以使用synchronized解決高併發下秒殺功能,這樣程式在併發下訪問效率下降,若用nginx反向 啟用分布式應用,synchronized則實現不了分布式鎖,如何解決?利用redis中的setnx可實現高併發下分布式鎖。具體要點和細節記錄在 ...
高併發伺服器 nginx實現負載均衡的幾種方式
要理解負載均衡,必須先搞清楚正向 和反向 正向 與反向 總結 注 正向 的是使用者。反向 的是伺服器 什麼是負載均衡 當一台伺服器的單位時間內的訪問量越大時,伺服器壓力就越大,大到超過自身承受能力時,伺服器就會崩潰。為了避免伺服器崩潰,讓使用者有更好的體驗,我們通過負載均衡的方式來分擔伺服器壓力。我...