package tech.lingjia.common.controller;

import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.LockSupport;

/**
 * @author heaven
 * @date 2023/2/26 14:16
 */
public class MyLock {

    /**
     * 锁状态
     */
    private AtomicInteger lockState = new AtomicInteger(0);
    /**
     * 获取到锁的线程
     */
    private Thread getLockThread = null;
    /**
     * 没有获取到锁的线程
     */
    private ConcurrentLinkedDeque<Thread> concurrentLinkedDeque = new ConcurrentLinkedDeque<>();
    /**
     * 加锁
     */
    public boolean lock(){
        //循环获取锁
        for (;;){
            if(compareAndSet(0,1)){
                //获取到锁、记录当前获取到锁的线程
                getLockThread = Thread.currentThread();
                return true;
            }
            //没有获取到锁、将线程加入队列
            concurrentLinkedDeque.add(Thread.currentThread());
            //阻塞
            LockSupport.park();
        }
    }

    /**
     * 修改锁状态
     */
    private boolean compareAndSet(int expect,int update){
        return lockState.compareAndSet(expect,update);
    }

    /**
     * 释放锁
     */
    public boolean unLock(){
        //当前没有线程获取到锁
        if(getLockThread == null){
            return false;
        }
        //获取到锁的是否是当前线程
        if(getLockThread == Thread.currentThread()){
            //修改锁状态
            boolean result = compareAndSet(1, 0);
            //修改成功
            if(result){
                //唤醒线程(公平锁)
                if(!concurrentLinkedDeque.isEmpty()){
                    Thread first = concurrentLinkedDeque.getFirst();
                    LockSupport.unpark(first);
                    return true;
                }

            }
        }
        return false;
    }
}