一、新的goroutine申請鎖時,發現鎖被佔用了。但自己滿足自旋條件,於是自己自旋,並設置上的Woken標記。此時佔用鎖的goroutine在釋放鎖時,檢查Woken標記,如果被標記。哪怕現在鎖上面的阻塞隊列不為空,也不做喚醒。直接return,讓自旋著的goroutine有更大機會搶到鎖。
二、釋放鎖時,檢查Woken標記為空。而阻塞隊列裏有goroutine需要被喚醒。那麼在喚醒時,同時標記鎖Woken。這裡可能有疑問,原來沒有Woken標記,為什麼在喚醒一個goroutine要主動標記呢?目的是保證鎖公平。
考慮這樣的場景:現在阻塞隊列裏只有一個goroutine。把它喚醒後,還得等調度器運行到它,它自己再去搶鎖。但在調度器運行到它之前,很可能新的競爭者參與進來,此時鎖被搶走的概率就很大。
但排隊的問題也很明顯,排隊阻塞喚醒的切換成本(這是損耗性能的潛在的隱患,下面Mutex的問題有舉例)。假如臨界區代碼執行只需要十幾個時鐘週期時,讓競爭者自旋等待一下,立刻就可以獲得鎖。減少不必要的切換成本,效率更高。