CLH自旋锁
2016-02-21 13:16
155 查看
CLH锁即Craig, Landin, and Hagersten (CLH) locks,CLH锁是一个自旋锁,能确保无饥饿性,提供先来先服务的公平性。
CLHLock的java实现逻辑:
myPred主要是记录前驱结点,在unlock时回收前驱结点; 因为tail获得当前结点的后继引用,那么当同一线程再次调用lock()的时候就会出现自身就是自己的前驱,while就无限循环了;
还有一种情况: 线程A ,B , A是b的前驱线程; A unlock后,又运行lock()方法 而此时cpu并没有切换到B执行,node.locked = true; B的前驱是A,A再次设置结点为True,导致B也得不到执行; 因此 unlock后, myNode必须换新的结点;
CLHLock的java实现逻辑:
public class CLHLock implements Lock { private final AtomicReference tail; private final ThreadLocal myPred; private final ThreadLocal myNode; public CLHLock() { tail = new AtomicReference(new QNode()); myNode = new ThreadLocal() { protected QNode initialValue() { return new QNode(); } }; myPred = new ThreadLocal(); } @Override public void lock() { QNode node = myNode.get(); node.locked = true; QNode pred = tail.getAndSet(node); myPred.set(pred); while (pred.locked) { } } @Override public void unlock() { QNode node = myNode.get(); node.locked = false; myNode.set(myPred.get()); } private static class QNode { volatile boolean locked; } }
myPred主要是记录前驱结点,在unlock时回收前驱结点; 因为tail获得当前结点的后继引用,那么当同一线程再次调用lock()的时候就会出现自身就是自己的前驱,while就无限循环了;
还有一种情况: 线程A ,B , A是b的前驱线程; A unlock后,又运行lock()方法 而此时cpu并没有切换到B执行,node.locked = true; B的前驱是A,A再次设置结点为True,导致B也得不到执行; 因此 unlock后, myNode必须换新的结点;
相关文章推荐
- Linux 下 SVN 常用命令
- ucos实时操作系统学习笔记——任务间通信(队列)
- java中super的两种方法
- 使用Solrj 获取语句分词结果的代码
- BZOJ 4032: [HEOI2015]最短不公共子串 后缀自动机 暴力
- Java数学表示式解析工具- jeval
- POJ_P2104 K-th Number(主席树)
- 第一篇博客
- 面向对象设计的SOLID原则
- 计算机专业英语 学习笔记 2
- UVa 1586, Molar Mass
- 模板_主席树
- Bestcoder Round #73 (div.2)
- JAVA ServerSocket 简单web服务器
- 【js】 古怪的 arguments
- java并发库--锁
- Android应用程序及其主要结构
- oracle之连接实战
- ios架构设计的方法论
- spark源码学习(八)--- executor启动task分析