package com.qmth.boot.core.concurrent.model;

import java.util.concurrent.atomic.AtomicReference;

/**
 * MCS算法实现的公平自旋锁
 */
public class McsLock {

    private AtomicReference<McsNode> tail;

    private ThreadLocal<McsNode> threadLocal;

    public McsLock() {
        this.tail = new AtomicReference<>();
        this.threadLocal = ThreadLocal.withInitial(McsNode::new);
    }

    public void lock() {
        McsNode current = threadLocal.get();
        McsNode previous = tail.getAndSet(current);
        if (previous != null) {
            current.locked = true;
            previous.next = current;
            while (current.locked) {
                //等待前置节点结束，更新当前节点状态
            }
        }
    }

    public void unlock() {
        McsNode current = threadLocal.get();
        if (current.next == null) {
            if (tail.compareAndSet(current, null)) {
                return;
            }
            while (current.next == null) {
                //等待后置节点完成加入，更新当前节点后置引用
            }
        }
        current.next.locked = false;
        current.next = null;
    }

    private static class McsNode {

        private volatile boolean locked = false;

        private volatile McsNode next = null;

    }
}
