几种锁算法的实现
来源:互联网 发布:网络拒绝接入华为 编辑:程序博客网 时间:2024/05/18 00:25
Multicore
Abstract
4种Lock的实现:
- TASLock
- TTASLock
- CLHLock
- MCSLock
TASLock
每一个Lock带有一个状态位,lock()与unlock()操作原子的改变状态位。
false时可进入,true时spin。
public class TASLock implements Lock{ AtomicBoolean state = new AtomicBoolean(false); public void lock() { while(state.getAndSet(true)) {} } public void unlock() { state.set(false); }}
defect:
- 在锁被其他线程持有的情况下,
while(state.getAndSet(true))
会不停的将
state从true改为true
TTASLock
TASLock算法的改进。
public class TTASLock implements Lock(){ AtomicBoolean state = new AtomicBoolean(false); public void lock() { while (true) { while (state.get()) {}; if (! state.getAndSet(true)) return; } } public void unlock() { state.set(false); }}
while (state.get()){}
是一个改进,效果是先看一眼lock的状态,当lock是false时,
再真正的执行state.getAndSet(true)
。- 当state.getAndSet(true) 的return为false时,说明之前的确是false,于是获得锁,return。
否则回到while(true),再次尝试获得锁。
defect:
- 在unlock时,state.set(false)还是会带来大量的cache miss。
cache miss VS cache hit
CLHLock
队列锁。
CLHLock
void initCLHlock(){ q.locked = FALSE; tail = &q;}void lock(){ QNode* qnode = (QNode*)pthread_getspecific(myNode); qnode->locked = TRUE; QNode* pred = getAndSet(qnode);//原子的得到队尾,并将qnode设为新的队尾。 pthread_setspecific(myPred, pred); while(pred->locked) { }}void unlock(){ QNode* qnode = (QNode*)pthread_getspecific(myNode); qnode->locked = FALSE; QNode* pred = (QNode*)pthread_getspecific(myPred); pthread_setspecific(myNode, pred);//unlock时必须将myNode指向前面的Node}
NOTE:
- unlock时必须将myNode指向前面的Node!
> 后果:如果Thread A unlock()后,紧接着又进入
队尾, A的locked会再次被置为TRUE, Thread B还在看着Thread A 的locked字段,于是产生
deadlock。 - 初始时教室里面有一个空凳子, 每个学生来到门口排队时都自己带着一个凳子。
MCSLock
public class MCSLock implements Lock{ AtomicReference<QNode> tail; ThreadLocal<QNode> myNode; public MCSLock() { queue = new AtomicReference<QNode>(null); myNode = new ThreadLocal<QNode>() { protected QNode initialValue() { return new QNode(); } }; } ... class QNode { boolean locked = false; QNode next = null;//与CLHLock相比,多了这个真正的next }} public void lock(){ QNode qnode = myNode.get(); QNode pred = tail.getAndSet(qnode); if (pred != null) { qnode.locked = true; pred.next = qnode; //wait until predecessor gives up the lock while(qnode.locked){}//将自己设为true然后spin,看似deadlock }}public void unlock(){ QNode qnode = myNode.get(); if (qnode.next == null) //后面没有等待线程的情况 {//------there is a gap!!!! if (tail.compareAndSet(qnode, null)) return; //真的没有等待线程,则直接返回,不需要通知 //wait until predecessor fills in its next field while (qnode.next == null){} } //右面有等待线程,则通知后面的线程 qnode.next.locked = false; qnode.next = null;}
NOTE:
- unlock()要要特别的注意。
Summary
- CLHLock的思想是当前线程在前一个线程的node上spin,每个线程unlock时修改自身的标记。
在共享总线结构下性能可以,无法应对分布式。 - MCSLock 用于解决分布式并行的问题。每个线程都在自己的node上spin,当释放锁时通知
后面的线程。
0 0
- 几种锁算法的实现
- 梅西迭代算法的实现
- CRC算法的实现...
- Hanoi的实现算法
- 图算法的实现
- LRU算法的实现
- 组合算法的实现
- kruskal算法的实现
- KMP算法的实现
- 排序算法的实现
- RSA算法的实现
- PID算法的实现
- Adler32算法的实现
- LRU算法的实现
- 实现好的算法
- Dijkstra算法的实现
- AC_BM算法的实现
- 排序算法的实现
- 互联网的江湖:十年轮回,借江山一用,可曾留下痕迹
- 十分钟学会初步使用Spring_注解篇
- 保留代码
- AS之rename project以及copy project
- centos7安装jdk-8u45-linux-x64.tar.gz
- 几种锁算法的实现
- 负载均衡VIP /LVS 的健康检测方式
- 解决 Source Insight中的parse too complex问题
- mac下配置svn服务器详解及用户的权限管理(亲测)
- IOS 百度地图一直报 manager start failed!
- Redis数据持久化
- Linux dd命令全面解析 [转载]
- c#system.InvalidOperation 当传递已修改行的datarow集合时,更新要求有效的 UpdateCommand。
- 编译脚本