// 这里之所以要忙等是因为:step 1执行完后,step 2可能还没执行完
while (currentThread.next == null) { // step 5
}
}
}
currentThread.next.isBlock = false;
currentThread.next = null;// for GC
}
}
CLH锁CLH锁也是一种基于链表的可扩展、高性能、公平的自旋锁,申请线程只在本地变量上自旋,它不断轮询前驱的状态,如果发现前驱释放了锁就结束自旋 。
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
public class CLHLock {
public static class CLHNode {
private volatile boolean isLocked = true; // 默认是在等待锁
【自旋锁、排队自旋锁、MCS锁、CLH锁】}
@SuppressWarnings("unused" )
private volatile CLHNode tail ;
private static final AtomicReferenceFieldUpdater<CLHLock, CLHNode> UPDATER = AtomicReferenceFieldUpdater
. newUpdater(CLHLock.class, CLHNode .class , "tail" );
public void lock(CLHNode currentThread) {
CLHNode preNode = UPDATER.getAndSet( this, currentThread);
if(preNode != null) {//已有线程占用了锁,进入自旋
while(preNode.isLocked ) {
}
}
}
public void unlock(CLHNode currentThread) {
// 如果队列里只有当前线程,则释放对当前线程的引用(for GC) 。
if (!UPDATER .compareAndSet(this, currentThread, null)) {
// 还有后续线程
currentThread. isLocked = false ;// 改变状态,让后续线程结束自旋
}
}
}
CLH锁 与 MCS锁 的比较下图是CLH锁和MCS锁队列图示:

文章插图
差异:
- 从代码实现来看,CLH比MCS要简单得多 。
- 从自旋的条件来看,CLH是在前驱节点的属性上自旋,而MCS是在本地属性变量上自旋 。
- 从链表队列来看,CLH的队列是隐式的,CLHNode并不实际持有下一个节点;MCS的队列是物理存在的 。
- CLH锁释放时只需要改变自己的属性,MCS锁释放则需要改变后继节点的属性 。
- CLH锁可以更容易地去实现“取消 (cancellation)”和“超时”功能,
推荐阅读
- 一文读懂线性回归、岭回归和Lasso回归
- 冠军!恭喜南安石井古山小学、水头朴里小学!?
- 花茶、药枕 特色疗法治失眠
- 荷叶茶有减肥、降血压功效
- 高丽参的功效、高丽参的作用 高丽参作用
- 故宫、动物园、十三陵……景区陆续开放,这份攻略请收好!
- 手机忘记锁屏密码怎么办oppo oppo手机忘记密码怎么办怎么解锁
- 线程锁系列:CLH Lock
- CPU频率是什么?主频、睿频和超频哪个更重要?
- Linux :磁盘分区、挂载知多少?
