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同步锁的一种变形.其主要从两方面进行了改造:节点的结构与节点等待机制.在结构上引入了头 ...
随机推荐
- Reverse Nodes in k-Group leetcode java
题目: Given a linked list, reverse the nodes of a linked list k at a time and return its modified list ...
- Java基础(四):Java Number & Math 类、Character 类、String 类、StringBuffer & StringBuilder 类
一.Java Number & Math 类: 1.Number类: 一般地,当需要使用数字的时候,我们通常使用内置数据类型,如:byte.int.long.double 等.然而,在实际开发 ...
- 以太网帧、IP报文格式
这几天完成一个对比以太网帧的程序(c语言),老师给了以太网帧头部和IP报文头部的结构体,跟实际抓取到的数据包的格式是相同的. 以太网帧头部的数据结构: typedef struct { unsigne ...
- [Algorithm] Tower Hopper Problem
By given an array of number, each number indicate the number of step you can move to next index: For ...
- [Sass] Level 3: Mixin -- Ex
When to use MIXIN? Better way to use MIXIN is when you deal with browser prefiex, for example: @mixi ...
- PHPCMS增加投票选项代码
<script src="jquery-1.10.1.js"></script> <tr> <th width="20%&quo ...
- 【OpenCV新手教程之十七】OpenCV重映射 & SURF特征点检測合辑
本系列文章由@浅墨_毛星云 出品.转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/30974513 作者:毛星云(浅墨) ...
- lenovo E431 win8系统 安装win7
事由:新买的lenovo e431 原装win8系统.win8系统本来就不好用,又傻傻的装了win10的预览版,丑死不说,还各种驱动不兼容,每次开机都提示不兼容——本人有点洁癖,见不得这种,本想把不兼 ...
- 【Linux】通过SSH修改调整Linux时间和时区
VPS(Virtual Private Server 虚拟专用服务器)技术,将一部服务器分割成多个虚拟专享服务器的一种服务.大多站长喜欢用美国的VPS,而美国的时间和时区和国内不同,那就需要通过SSH ...
- -Prefix.pch has been modified 的错误修复
方法一: 选择 Product > Clean 然后重新编译--运行: 方法二: 找到-Prefix.pch文件,把中间的 #ifdef __OBJC__ #import <UIKit/U ...