CLH队列锁
http://blog.csdn.net/aesop_wubo/article/details/7533186
CLH锁即Craig, Landin, and Hagersten (CLH) locks。CLH锁是一个自旋锁。能确保无饥饿性。提供先来先服务的公平性。
CLH锁也是一种基于链表的可扩展、高性能、公平的自旋锁,申请线程仅仅在本地变量上自旋,它不断轮询前驱的状态,假设发现前驱释放了锁就结束自旋。
CLH算法实现
结点之间是通过隐形的链表相连,之所以叫隐形的链表是由于这些结点之间没有明显的next指针,而是通过myPred所指向的结点的变化情况来影响myNode的行为。
CLHLock上另一个尾指针,始终指向队列的最后一个结点。
CLHLock的类图例如以下所看到的:

当一个线程须要释放锁时,将当前结点的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 = new AtomicReference<QNode>(new QNode());
- 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());
- }
- }
从代码中能够看出lock方法中有一个while循环,这 是在等待前趋结点的locked域变为false。这是一个自旋等待的过程。unlock方法非常easy。仅仅须要将自己的locked域设置为false就可以。
CLH优缺点
一种解决NUMA系统结构的思路是MCS队列锁。
參考资料:
CLH队列锁的更多相关文章
- 【Java并发编程实战】-----“J.U.C”:CLH队列锁
在前面介绍的几篇博客中总是提到CLH队列,在AQS中CLH队列是维护一组线程的严格按照FIFO的队列.他能够确保无饥饿,严格的先来先服务的公平性.下图是CLH队列节点的示意图: 在CLH队列的节点QN ...
- 可重入锁 公平锁 读写锁、CLH队列、CLH队列锁、自旋锁、排队自旋锁、MCS锁、CLH锁
1.可重入锁 如果锁具备可重入性,则称作为可重入锁. ========================================== (转)可重入和不可重入 2011-10-04 21:38 这 ...
- Java 并发编程学习笔记 理解CLH队列锁算法
CLH算法实现 CLH队列中的结点QNode中含有一个locked字段,该字段若为true表示该线程需要获取锁,且不释放锁,为false表示线程释放了锁.结点之间是通过隐形的链表相连,之所以叫隐形的链 ...
- 【Java并发编程实战】-----“J.U.C”:CLH队列锁
在前面介绍的几篇博客中总是提到CLH队列,在AQS中CLH队列是维护一组线程的严格依照FIFO的队列.他可以确保无饥饿,严格的先来先服务的公平性.下图是CLH队列节点的示意图: 在CLH队列的节点QN ...
- 并发之AQS原理(二) CLH队列与Node解析
并发之AQS原理(二) CLH队列与Node解析 1.CLH队列与Node节点 就像通常医院看病排队一样,医生一次能看的病人数量有限,那么超出医生看病速度之外的病人就要排队. 一条队列是队列中每一个人 ...
- 并发系列(3)之 CLH、MCS 队列锁简介
这篇博客主要是作为 AbstractQueuedSynchronizer 的背景知识介绍:平时接触也非常的少,如果你不感兴趣可以跳过:但是了解一下能更加的清楚 AQS 的设计思路: 一.自旋锁简介 通 ...
- 从ReentrantLock实现非公平锁的源码理解AQS中的CLH队列
虽然前面也看过AQS的文章,并且转载过一篇大佬的分析,但是我觉得他们对于AQS和ReentrantLock部分的源码的分析并不详细,自己理解期来还是有问题,于是自己准备花时间重新梳理下,好了,进入正题 ...
- AQS(一) 对CLH队列的增强
基本概念 AQS(AbstractQueuedSynchronizer),顾名思义,是一个抽象的队列同步器. 它的队列是先进先出(FIFO)的等待队列 基于这个队列,AQS提供了一个实现阻塞锁的机制 ...
- 【Java并发编程实战】----- AQS(四):CLH同步队列
在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形.其主要从两方面进行了改造:节点的结构与节点等待机制.在结构上引入了头 ...
随机推荐
- Java基础(十二):包(package)
一.Java 包(package): 为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间.包的作用: 1.把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用. 2.如同文件夹 ...
- 网络结构设计——负载均衡之LVS学习笔记(二)
LVS按个人理解的说就是将一台Linux服务器当作路由器等功能的技术.LVS---Linux虚拟服务器. LVS实现了三种IP负载均衡技术VS/NAT.VS/TUN.VS/DR. 今天简单分享一下我在 ...
- ajax局部刷新一个div下的jsp
用AJAX刷新一个DIV中的jsp内容 <script type="text/javascript"> var xmlhttp; function startrefre ...
- [CSS3] Parent relative and child absoulte
如果在一个容器中的子元素使用了position:absolute, 那么他可能会跑出父元素的框架范围. 如果想限定子元素在付元素的框架范围,可以在父元素上加position:relative; 对于一 ...
- Jmeter测试报告可视化(Excel, html以及jenkins集成)
做性能测试通常在none GUI的命令行模式下运行Jmeter. 例如: jmeter -n -t /opt/las/JMeter/TestPlan/test.jmx -l /opt/las/JMet ...
- asp.net网站项目调用page,或者ashx页面不能用反射
public class TestHandler : System.Web.IHttpHandler { public bool IsReusable { get { return false; } ...
- struct、union、enum and sizeof
struct 1.结构体和数组的差别:能够再结构体里声明数组.结构体变量能够相互赋值.而数组不行. 2.struct与class的差别:class的成员訪问权限默认是private,而struct成员 ...
- mac 下vim 配置文件
" Configuration file for vim set modelines=0 " CVE-2007-2438 " Normally we use vim-ex ...
- CAD批量合并文件
要求:将整饰完成504幅单独的宗地图合并成一张总图,合并后,去掉其他要素,只保留毕合的权属线. 解决: 1.合并dwg文件,除了手工粘贴复制外,最先想到的是插入块,即用Insert命令插入,测试结果可 ...
- ZH奶酪:PHP中添加HTML代码的三种方法
php中添加HTML代码,就是php类型的文件中添加html代码~ 第一种是在HTML中加PHP. 大段大段的html代码中,在各个需要执行php的地方<?php .... ?> 比如 l ...