Ceci est un CLH-Lock en Java typique:Pourquoi CLH verrouillage besoin prev-nœud en java
public class CLHLock{
private final AtomicReference tail;
// why we need this node?
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();
}
public void lock() {
QNode node = myNode.get();
node.locked = true;
QNode pred = tail.getAndSet(node);
// this.myPred == pred
myPred.set(pred);
while (pred.locked) {
}
}
public void unlock() {
QNode node = myNode.get();
node.locked = false;
// this.myNode == this.myPred
myNode.set(myPred.get());
}
private static class QNode {
volatile boolean locked;
}
}
Pourquoi nous avons besoin myPred
Noeud, seulement deux endroits utilisé cette variable:
this.prev.set(pred);
- Liste item
this.node.set(this.prev.get());
quand nous avons fait, this.prev == this.node == pred
?
Peut-être que nous pouvons en œuvre comme ceci:
public class CLHLock {
// Node tail
private final AtomicReference<QNode> tail = new AtomicReference<>(new QNode());
// ThreadLocal
private final ThreadLocal<QNode> node = ThreadLocal.withInitial(QNode::new);
public void lock() {
QNode now = node.get();
now.locked = true;
// spin on pre-node
QNode pre = tail.getAndSet(now);
while (pre.locked) {
}
}
public void unlock() {
QNode now = node.get();
now.locked = false;
}
class QNode {
volatile boolean locked = false;
}
}
Quelle est la différence entre les deux ci-dessus?