CLH(Craig, Landin, and Hagersten locks)机制
CLH(Craig, Landin, and Hagersten locks):
- 是一个自旋锁,能确保无饥饿性,提供先来先服务的公平性。
- CLH锁也是一种基于链表的可扩展、高性能、公平的自旋锁,申请线程只在本地变量上自旋,它不断轮询前驱的状态,如果发现前驱释放了锁就结束自旋。
- AQS就是基于CLH队列,AQS是将每一条请求共享资源的线程封装成一个CLH锁队列的一个结点(Node),来实现锁的分配。
当一个线程需要获取锁时:
1 创建一个的QNode,将其中的locked设置为true表示需要获取锁
2.线程对tail域调用getAndSet方法,使自己成为队列的尾部,同时获取一个指向其前趋结点的引用myPred
3.该线程就在前趋结点的locked字段上旋转,直到前趋结点释放锁
4.当一个线程需要释放锁时,将当前结点的locked域设置为false,同时回收前趋结点
如下图,线程A需要获取锁,其myNode域为true,tail指向线程A的结点,然后线程B也加入到线程A后面,tail指向线程B的结点。然后线程A和B都在其myPred域上旋转,一旦它的myPred结点的locked字段变为false,它就可以获取锁。明显线程A的myPred locked域为false,此时线程A获取到了锁。
public class CLHLock implements Lock { AtomicReference<QNode> tail ; ThreadLocal<QNode> myPred; ThreadLocal<QNode> myNode; public CLHLock() { tail = new AtomicReference<QNode>(new QNode()); myNode = new ThreadLocal<QNode>() { protected QNode initialValue() { return new QNode(); } }; myPred = new ThreadLocal<QNode>() { protected QNode initialValue() { return null; } }; } @Override public void lock() { QNode qnode = myNode.get(); qnode.locked = true; QNode pred = tail.getAndSet(qnode); myPred.set(pred); while (pred.locked) { } } @Override public void unlock() { QNode qnode = myNode.get(); qnode.locked = false; myNode.set(myPred.get()); }
}
CLH分析
CLH队列锁的优点是空间复杂度低(如果有n个线程,L个锁,每个线程每次只获取一个锁,那么需要的存储空间是O(L+n),n个线程有n个myNode,L个锁有L个tail),CLH的一种变体被应用在了JAVA并发框架中(AbstractQueuedSynchronizer.Node)。CLH在SMP系统结构下该法是非常有效的。但在NUMA系统结构下,每个线程有自己的内存,如果前趋结点的内存位置比较远,自旋判断前趋结点的locked域,性能将大打折扣。
一种解决NUMA系统结构的思路是MCS队列锁
MSC与CLH最大的不同并不是链表是显示还是隐式,而是线程自旋的规则不同:CLH是在前趋结点的locked域上自旋等待,而MCS是在自己的结点的locked域上自旋等待。正因为如此,它解决了CLH在NUMA系统架构中获取locked域状态内存过远的问题。
MCS队列锁的具体实现如下:
a. 队列初始化时没有结点,tail=null
b. 线程A想要获取锁,于是将自己置于队尾,由于它是第一个结点,它的locked域为false
c. 线程B和C相继加入队列,a->next=b,b->next=c。且B和C现在没有获取锁,处于等待状态,所以它们的locked域为true,尾指针指向线程C对应的结点
d. 线程A释放锁后,顺着它的next指针找到了线程B,并把B的locked域设置为false。这一动作会触发线程B获取锁
转自
CLH(Craig, Landin, and Hagersten locks)机制相关推荐
- CLH锁 、MCS锁
一. 1.SMP(Symmetric Multi-Processor) SMP(Symmetric Multi-Processing)对称多处理器结构,指服务器中多个CPU对称工作,每个CPU访问内存 ...
- Java 中的各种锁及其原理
文章目录 概览 Synchronized锁 Synchronized 锁的底层类别 不同锁下对象头中的内容 偏向锁 轻量级锁 轻量级锁加锁过程 字节码层面 synchronized关键字最主要的三种使 ...
- java队列加锁_java并发-----浅析ReentrantLock加锁,解锁过程,公平锁非公平锁,AQS入门,CLH同步队列...
前言 为什么需要去了解AQS,AQS,AbstractQueuedSynchronizer,即队列同步器.它是构建锁或者其他同步组件的基础框架(如ReentrantLock.ReentrantRead ...
- 并发编程面试题(2021最新版)
目录 基础知识 并发编程的优缺点 为什么要使用并发编程(并发编程的优点) 并发编程有什么缺点 并发编程三要素是什么?在 Java 程序中怎么保证多线程的运行安全?并发编程三要素(线程的安全性问题体现在 ...
- Java并发编程面试题(2020最新版)
转载自 Java并发编程面试题(2020最新版) 基础知识 并发编程的优缺点 为什么要使用并发编程(并发编程的优点) 充分利用多核CPU的计算能力:通过并发编程的形式可以将多核CPU的计算能力发挥到 ...
- 05.抽象队列同步器AQS应用之Lock详解
AQS应用之Lock Java并发编程核心在于java.concurrent.util包而juc当中的大多数同步器实现都是围绕着共同的基础行为,比如等待队列.条件队列.独占获取.共享获取等,而这个行为 ...
- 并发容器J.U.C -- AQS组件(一)
AQS简介 AQS全名:AbstractQueuedSynchronizer,是并发容器J.U.C(java.lang.concurrent)下locks包内的一个类.它实现了一个FIFO的队列.底层 ...
- 面试官:多线程硬核50问!能回答一半就让你过
前言 金九银十快要来了,整理了50道多线程并发面试题,大家可以点赞.收藏起来,慢慢品!~ 1.为什么要使用多线程 选择多线程的原因,就是因为快.举个例子: 如果要把1000块砖搬到楼顶,假设到楼顶有几 ...
- 一文让你彻底了解多线程
伙伴们很抱歉,因为最近需要粉丝突破1000,所以很多文章都设置了仅粉丝可见,如果大家看完这篇文章感觉对自己没啥帮助,可以在取消关注!!! 本文篇幅很长,建议大家分段阅读,如果你准备面试,那么就请你一定 ...
- java个人整理知识点
发展: 1.SE 标准版. 2.EE 企业版,基于SE. 3.ME 已经淘汰. JDK.JRE和JVM: JDK: 称为Java开发工具包( Java Development Kit).Java开发人 ...
最新文章
- Spring整合JMS(四)——事务管理
- PSXDMS cassandra testing
- 使用WebClient 获得网页内容或提交请求
- Zookeeper_简介
- AWS public key的邮件验证方式
- Java注解原理学习之@Cacheable debug
- 什么是mysql事物定义_Mysql事务原理
- python网站后台_Python 网站后台扫描脚本
- python后端面试题
- “云”话数字经济:2020 腾讯全球数字生态大会定档 9 月!​
- 【C++笔记】构造函数与析构函数相关知识
- IcedTea6 1.7.6、1.8.3和1.9.2补丁程序信息泄漏
- [RK3288][Android6.0] Audio中的HW Params设置流程
- 插入移动硬盘提示格式化怎么办?数据还有机会找回吗
- 字体 流光css,实例详解CSS3制作文字流光渐变特效
- 2022年~全网最真实的软件测试面试题合集
- 五年了还在原地踏步咋整?技术大佬给你整理了一套切实可行的方法论
- yolov8 做图片分类和 ResNet Efficientnet 等常用分类网络的对比
- 北邮邮箱配置客户端教程(如Windows自带邮件)
- 阿里云oss 收费标准细则,太鸡贼了,不要傻傻的以为只收你存储的钱
热门文章
- word文档中表格顶头怎么调整_word使用技巧之-Word文字处理技巧,学会不求人!...
- 第十三周作业-必做3
- python实现插值填充有序均匀点云空洞
- 工业相机和镜头选型技巧
- 哪个学校计算机考研945,2018年郑州大学945软件工程专业基础综合考研复习资料...
- 02读书笔记:《编码》-隐匿在计算机软硬件背后的语言(12-14章)
- 无插件使用Eclipse和Resin调试WEB应用(Debug Web App In Ecli...
- 爬虫出现selenium.common.exceptions.NoSuchWindowException: Message: Browsing context has been discarded
- 餐厅点菜c语言程序代码,餐馆点菜系统C语言源代码.pdf
- 【JAVA SE】三万字终极魔典 面向对象编程深度讲解(包+继承+多态+抽象类+接口 全面剖析)