几种自旋锁SpinLock,TicketLock,CLHLock,以及可重入实现要点,非阻塞锁实现要点
来源:互联网 发布:淘宝白夜追凶视频电话 编辑:程序博客网 时间:2024/04/30 14:39
最核心的东西:synchronization state,同步状态:指示当前线程是否可以proceed还是需要wait的状态。
1.普通SpinLock (支持可重入的版本)
class SpinLock {// use thread itself as synchronization stateprivate AtomicReference<Thread> owner = new AtomicReference<Thread>(); private int count = 0; // reentrant count of a thread, no need to be volatilepublic void lock() {Thread t = Thread.currentThread();if (t == owner.get()) { // if re-enter, increment the count.++count;return;}while (owner.compareAndSet(null, t)) {} //spin}public void unlock() {Thread t = Thread.currentThread();if (t == owner.get()) { //only the owner could do unlock;if (count > 0) --count; // reentrant count not zero, just decrease the counter.else {owner.set(null);// compareAndSet is not need here, already checked}}}}
为什么用Thread 本身当 同步状态而不是一个简单的boolean flag? 因为可以携带更多信息(当前owning thread)
1) 支持可重入,判断是否是重入,重入不需要改变同步状态,而只需要计数
2)确保只有锁的拥有者才能做unlock
2 TicketLock
思路:类似银行办业务,先取一个号,然后等待叫号叫到自己。好处:保证FIFO,先取号的肯定先进入。而普通的SpinLock,大家都在转圈,锁释放后谁刚好转到这谁进入。
class TicketLock {private AtomicInteger serviceNum = new AtomicInteger(0);private AtomicInteger ticketNum = new AtomicInteger(0);private static final ThreadLocal<Integer> myNum = new ThreadLocal<Integer>();public void lock () {myNum.set(ticketNum.getAndIncrement());while (serviceNum.get() != myNum.get()) {};}public void unlock() {serviceNum.compareAndSet(myNum.get(), myNum.get() + 1);}}
3 CLHLock
CLH好处
1)公平,FIFO,先来后到的顺序进入锁
2)而且没有竞争同一个变量,因为每个线程只要等待自己的前继释放就好了。
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;}};}@Overridepublic void lock() {QNode qnode = myNode.get();qnode.locked = true;QNode pred = tail.getAndSet(qnode);myPred.set(pred);while (pred.locked) {}}@Overridepublic void unlock() {QNode qnode = myNode.get();qnode.locked = false;myNode.set(myPred.get());}}
4 阻塞锁的实现
CLH每个线程lock 的时候 spin on 它的前驱,不park,unlock的时候,只需要修改自身状态,不需要唤醒(unpark)后继线程。而阻塞方式下,lock的时候需要park自己,unlock的时候要 unpark后继
package lock;import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;import java.util.concurrent.locks.LockSupport;public class CLHLock1 { public static class CLHNode { private volatile Thread isLocked; } @SuppressWarnings("unused") private volatile CLHNode tail; private static final ThreadLocal<CLHNode> LOCAL = new ThreadLocal<CLHNode>(); private static final AtomicReferenceFieldUpdater<CLHLock1, CLHNode> UPDATER =AtomicReferenceFieldUpdater.newUpdater(CLHLock1.class, CLHNode.class, "tail"); public void lock() { CLHNode node = new CLHNode(); LOCAL.set(node); CLHNode preNode = UPDATER.getAndSet(this, node); if (preNode != null) { preNode.isLocked = Thread.currentThread(); LockSupport.park(this); preNode = null; LOCAL.set(node); } } public void unlock() { CLHNode node = LOCAL.get(); if (!UPDATER.compareAndSet(this, node, null)) { System.out.println("unlock\t" + node.isLocked.getName()); LockSupport.unpark(node.isLocked); } node = null; }}
0 0
- 几种自旋锁SpinLock,TicketLock,CLHLock,以及可重入实现要点,非阻塞锁实现要点
- 几种自旋锁SpinLock,TicketLock,CLHLock,以及可重入实现要点,非阻塞锁实现要点
- nginx spinlock 自旋锁的实现
- nginx spinlock 自旋锁的实现
- 高性能自旋锁 MCS Spinlock 的设计与实现
- 自旋锁(Spinlock)加锁过程实现(arm平台)
- 高性能自旋锁 MCS Spinlock 的设计与实现
- 高性能自旋锁 MCS Spinlock 的设计与实现
- opencl:原子命令实现自旋锁(spinlock)的使用限制
- 高性能自旋锁 MCS Spinlock 的设计与实现
- linux 内核自旋锁spinlock实现详解(基于ARM处理器)
- linux 内核自旋锁spinlock实现详解(基于ARM处理器)
- 自旋锁spinlock
- 自旋锁 SpinLock
- 自旋锁spinlock
- 自旋锁 spinlock 理解
- 自旋锁(spinlock)
- Spinlock编程(自旋锁)
- 4. Phpstorm svn
- 兄弟会
- 删除CocoaPods中已经配置的类库、移除项目中CocoaPods
- ]利用shell脚本,crontab,scp实现将一台服务器的目录备份到另一台服务器
- 云计算时代告别phpMyAdmin
- 几种自旋锁SpinLock,TicketLock,CLHLock,以及可重入实现要点,非阻塞锁实现要点
- Android应用:ContentResolver内容观察者的使用
- 提示用户打开某些权限 (打开设置页面)
- Problem J: 写一个函数,使给定的一个二维数组(3×3)转置,即行列互换
- data.getData()返回的Uri
- textarea 光标处插入值
- Spark Streaming实时计算框架介绍
- 将Highcharts图表数据生成Table表格
- C++入门(5):定义个人函数