打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
CLH锁学习

CLH锁即Craig, Landin, and Hagersten (CLH) locks,CLH锁是一个自旋锁,能确保无饥饿性,提供先来先服务的公平性。
何谓自旋锁?它是为实现保护共享资源而提出一种锁机制。其实,自旋锁与互斥锁比较类似,它们都是为了解决对某项资源的互斥使用。无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个保持者,也就说,在任何时刻最多只能有一个执行单元获得锁。但是两者在调度机制上略有不同。对于互斥锁,如果资源已经被占用,资源申请者只能进入睡眠状态。但是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,"自旋"一词就是因此而得名。

CLHLock的java实现逻辑:

 

Java代码  
  1. public class CLHLock implements Lock {  
  2.     private final AtomicReference tail;  
  3.     private final ThreadLocal myPred;  
  4.     private final ThreadLocal myNode;  
  5.   
  6.     public CLHLock() {  
  7.         tail = new AtomicReference(new QNode());  
  8.         myNode = new ThreadLocal() {  
  9.             protected QNode initialValue() {  
  10.                 return new QNode();  
  11.             }  
  12.         };  
  13.   
  14.         myPred = new ThreadLocal();  
  15.     }  
  16.   
  17.     @Override  
  18.     public void lock() {  
  19.         QNode node = myNode.get();  
  20.         node.locked = true;  
  21.         QNode pred = tail.getAndSet(node);  
  22.         myPred.set(pred);  
  23.         while (pred.locked) {  
  24.         }  
  25.     }  
  26.   
  27.     @Override  
  28.     public void unlock() {  
  29.         QNode node = myNode.get();  
  30.         node.locked = false;  
  31.         myNode.set(myPred.get());  
  32.     }  
  33.   
  34.     private static class QNode {  
  35.         volatile boolean locked;  
  36.     }  
  37. }  
 


锁本身被表示成QNode的虚拟链表。共享的tail保存申请的最后的一个申请lock的线程的myNode域。每个申请lock的线程通过一个本地线程变量pred指向它的前驱。另外一个本地线程变量myNode的locked保存本身的状态,true:正在申请锁或已申请到锁;false:已释放锁。每个线程通过监视自身的前驱状态,自旋等待锁被释放。释放锁时,把自身myNode的locked设为false,使后继线程获的锁,并回收前驱的QNode,等待下次使用,因为自身的QNode可能被tail获后继引用,而前驱不再使用老的QNode。

AbstractQueuedSynchronizer的实现也是部分基于"CLH"队列的思想。具体见AbstractQueuedSynchronizer的doAcquireSharedInterruptibly方法实现
AbstractQueuedSynchronizer 为实现依赖于先进先出 (FIFO) 等待队列的阻塞锁定和相关同步器(信号量、事件,等等)提供一个框架。用java的人都知道synchronized能够对一个需要确保线程安全的对象,方法实现多线程并发控制,这是在java语法层次的实现,而AbstractQueuedSynchronizer 则是在应用层次而不是语法层次(更高的层次)提供了实现多线程并发控制组件的基础。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
CLH锁 、MCS锁
JAVA并发编程学习笔记之CLH队列锁
JAVA并发编程学习笔记之MCS队列锁 (比较清楚)
【Java并发编程实战】-----“J.U.C”:CLH队列锁
Java多线程系列
深入JVM锁机制2-Lock
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服