title: Why CLH Lock need prev-Node in java
body: <p>This is a typical CLH-Lock in java:</p>
  
  <pre><code>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;  
      }  
  }
  </code></pre>
  
  <p>Why we need <code>myPred</code> Node, only two places used this variable:</p>
  
  <ol>
  <li><code>this.prev.set(pred);</code></li>
  <li>List item <code>this.node.set(this.prev.get());</code></li>
  </ol>
  
  <p>when we done, <code>this.prev == this.node == pred</code> ?</p>
  
  <p>Maybe we can implements like this:</p>
  
  <pre><code>public class CLHLock {
      // Node tail
      private final AtomicReference&lt;QNode&gt; tail = new AtomicReference&lt;&gt;(new QNode());
  
      // ThreadLocal
      private final ThreadLocal&lt;QNode&gt; 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;
      }
  }
  </code></pre>
  
  <p>What is the difference between the above two? </p>