作者:MCS:John Mellor-Crummey and Michael Scott。 锁的名称都来源于发明人的名字首字母
MCS Spinlock是一种基于显式链表(节点里面拥有next指针)的可扩展、高性能、公平的自旋锁,申请线程只在本地变量上自旋,由直接前驱负责通知其结束自旋(与CLH自旋锁不同的地方,不在轮询前驱的状态,而是由前驱主动通知),从而极大地减少了不必要的处理器缓存同步的次数,降低了总线和内存的开销。而MCS是在自己的结点的locked域上自旋等待。正因为如此,它解决了CLH在NUMA系统架构中获取locked域状态内存过远的问题。
java实现
CLH队列中的节点QNode中含有一个locked字段,该字段若为true表示该线程需要获取锁,且不释放锁,为false表示线程释放了锁。
定义Node类
1 | public class QNode { |
定义Lock接口
1 | public interface Lock { |
定义CLHLock
1 | public class MCSLock implements Lock { |
CLH与MCS比较
CLH 对比 MCS
(1)都是基于链表,不同的是CLHLock是基于隐式链表,没有真正的后续节点属性,MCSLock是显示链表,有一个指向后续节点的属性。
(2)、将获取锁的线程状态借助节点(node)保存,每个线程都有一份独立的节点,这样就解决了TicketLock多处理器缓存同步的问题。
(3)从自旋的条件来看,CLH是在前驱节点的属性上自旋,而MCS是在本地属性变量上自旋。
(4)从链表队列来看,CLH的队列是隐式的,CLHNode并不实际持有下一个节点;MCS的队列是物理存在的。
(5)CLH锁释放时只需要改变自己的属性,MCS锁释放则需要改变后继节点的属性。
(6)CLH适合CPU个数不多的计算机硬件架构上,MCS则适合拥有很多CPU的硬件架构上
(7)CLH和MCS实现的自旋锁都是不可重入的
- 本文作者: 初心
- 本文链接: http://funzzz.fun/2021/05/19/MCSLock/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!