手动实现J.U.C下面的Lock锁

手动实现J.U.C下面的Lock锁

package com.app.lock.app;

import sun.misc.Unsafe;

import java.lang.reflect.Field;

public class MyLock {
    private  volatile int state;
    private  volatile Node head;
    private  volatile Node tail;
    private static Unsafe unsafe=null;
    private static  Long  stateOffset;
    private static  Long  headOffset;
    private static  Long  tailOffset;
    static {
        try {
            Field theUnsafe=Unsafe.class.getDeclaredField("theUnsafe");
            theUnsafe.setAccessible(true);
            unsafe=(Unsafe) theUnsafe.get(null);
            stateOffset = unsafe.objectFieldOffset(MyLock.class.getDeclaredField("state"));
            headOffset = unsafe.objectFieldOffset(MyLock.class.getDeclaredField("head"));
            tailOffset = unsafe.objectFieldOffset(MyLock.class.getDeclaredField("tail"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private boolean compareAndSetState(int oldVal,int newVal){
        return unsafe.compareAndSwapInt(this,stateOffset,oldVal,newVal);
    }
    private boolean compareAndSetTail(Node oldVal,Node newVal){
        return unsafe.compareAndSwapObject(this,tailOffset,oldVal,newVal);
    }
    public static void main(String[] args) {

    }
    private  static class Node{
        Thread thread;
        Node  prev;
        Node next;
        public Node(){
        }
        public Node(Thread thread,Node prev){
            this.thread=thread;
            this.prev=prev;
        }
    }
    public void lock(){
        //首先尝试获取锁
        if(compareAndSetState(0,1)){
            return;
        }
        Node node=enqueue();
        Node prev=node.prev;
        while (node.prev!=head||!compareAndSetState(0,1)){
            unsafe.park(false,0L);
        }
        //走到这里说明node前一个节点为head  head为空节点 代表当前正在执行的线程
        head=node;
        node.thread=null;
        //断开与原头节点的连接
        node.prev=null;
        prev.next=null;
    }
    public void unlock(){
        //单线程执行
        state=0;
        Node next=head.next;
        if(next!=null){
            unsafe.unpark(next.thread);
        }
    }
    private Node enqueue(){
        //入队 cas更新尾节点
        while (true){
            Node t=tail;
            Node node=new Node(Thread.currentThread(),t);
            if(compareAndSetTail(t,node)){
                t.next=node;
                return node;
            }
        }
    }


}