CLH锁即Craig, Landin, and Hagersten (CLH) locks,CLH锁是一个自旋锁,能确保无饥饿性,提供先来先服务的公平性。
CLHLock的java实现逻辑:
public class CLHLock implements Lock {
private final AtomicReference tail;
private final ThreadLocal myPred;
private final ThreadLocal myNode;
public CLHLock() {
tail = new AtomicReference(new QNode());
myNode = new ThreadLocal() {
protected QNode initialValue() {
return new QNode();
}
};
myPred = new ThreadLocal();
}
@Override
public void lock() {
QNode node = myNode.get();
node.locked = true;
QNode pred = tail.getAndSet(node);
myPred.set(pred);
while (pred.locked) {
}
}
@Override
public void unlock() {
QNode node = myNode.get();
node.locked = false;
myNode.set(myPred.get());
}
private static class QNode {
volatile boolean locked;
}
}
myPred主要是记录前驱结点,在unlock时回收前驱结点; 因为tail获得当前结点的后继引用,那么当同一线程再次调用lock()的时候就会出现自身就是自己的前驱,while就无限循环了;
还有一种情况: 线程A ,B , A是b的前驱线程; A unlock后,又运行lock()方法 而此时cpu并没有切换到B执行,node.locked = true; B的前驱是A,A再次设置结点为True,导致B也得不到执行; 因此 unlock后, myNode必须换新的结点;