package threaddemo.lock;

import java.util.concurrent.atomic.AtomicReference;

/**
 * demo class for CLH. code from
 * <a href="https://mp.weixin.qq.com/s/jEx-4XhNGOFdCo4Nou5tqg">Java AQS 核心数据结构-CLH 锁</a>
 */
public class CLH {
    private final ThreadLocal<Node> node = ThreadLocal.withInitial(Node::new);
    private final AtomicReference<Node> tail = new AtomicReference<>(new Node());

    private static class Node {
        private volatile boolean locked;
    }

    public void lock() {
        Node node = this.node.get();
        node.locked = true;
        Node pre = this.tail.getAndSet(node);
        while (pre.locked) ;
    }

    public void unlock() {
        final Node node = this.node.get();
        node.locked = false;
        this.node.set(new Node());
    }
}
