CLH自旋锁是一种基于隐式链表(节点里面没有next指针)的可扩展、高性能、公平的自旋锁,申请线程只在本地变量上自旋,它不断轮询前驱的状态,如果发现前驱释放了锁就结束自旋。CLH队列锁的优点是空间复杂度低(如果有n个线程,L个锁,每个线程每次只获取一个锁,那么需要的存储空间是O(L+n),n个线程有n个。myNode,L个锁有L个tail),CLH的一种变体被应用在了JAVA并发框架中。 CLH在SMP系统结构下该法是非常有效的。但在NUMA系统结构下,每个线程有自己的内存,如果前趋结点的内存位置比较远,自旋判断前趋结点的locked域,性能将大打折扣。
示例代码如下:
import java.util.concurrent.atomic.AtomicReference;运行效果
public class HelloWorld {
public static void main(String[] args) throws InterruptedException {
CLHLock lock=new CLHLock();
Runnable runnable=new Runnable() {
@Override
public void run() {
try {
lock.lock();
System.out.println(Thread.currentThread().getName()+" 获得锁 ");
//前驱释放,do own work
Thread.sleep(5000);
System.out.println(Thread.currentThread().getName()+" 释放锁 ");
lock.unlock();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread t1=new Thread(runnable,"线程1");
Thread t2=new Thread(runnable,"线程2");
Thread t3=new Thread(runnable,"线程3");
t1.start();
t2.start();
t3.start();
}
}
/**
* Created by qindongliang on 2018/8/5.
*/
class CLHLock {
class Node{
//false代表没人占用锁
volatile boolean locked=false;
}
//指向最后加入的线程
final AtomicReference<Node> tail=new AtomicReference<>(new Node());
//使用ThreadLocal保证每个线程副本内都有一个Node对象
final ThreadLocal<Node> current;
public CLHLock(){
//初始化当前节点的node
current=new ThreadLocal<Node>(){
@Override
protected Node initialValue() {
return new Node();
}
};
}
public void lock() throws InterruptedException {
//得到当前线程的Node节点
Node own=current.get();
//修改为true,代表当前线程需要获取锁
own.locked=true;
//设置当前线程去注册锁,注意在多线程下环境下,这个
//方法仍然能保持原子性,,并返回上一次的加锁节点(前驱节点)
Node preNode=tail.getAndSet(own);
//在前驱节点上自旋
while(preNode.locked){
System.out.println(Thread.currentThread().getName()+" 开始自旋.... ");
Thread.sleep(2000);
}
}
public void unlock(){
//当前线程如果释放锁,只要将占用状态改为false即可
//因为其他的线程会轮询自己,所以volatile布尔变量改变之后
//会保证下一个线程能立即看到变化,从而得到锁
current.get().locked=false;
}
}

网友回复
如何破解绕开seedance2.0真人照片生成视频 限制?
python有哪些算法可以将视频中的每个帧图片去除指定区域水印合成新的视频?
iphone的激光雷达数据能否实时传输到three三维空间中?
豆包sora等ai视频生成大模型生成的视频水印如何去除?
python如何实现在电脑上拨号打电话给手机?
具身机器人与人形机器人区别?
nodejs如何将一个完整的js代码文件切割成不同的部分混淆后动态加载进入html运行?
为啥windows.onerror捕获js错误是这样的{"message":"Script error.","source":"","lineno":0,"colno":0,"stack":null,
2026年ai将全面接管编程?
WebMCP是干啥的?


