简单实现一个lock

import java.lang.reflect.Field;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.locks.LockSupport;

import sun.misc.Unsafe;

public class MyLock {
    private static Unsafe unsafe;

    /**
     * 当前加锁状态,记录加锁的次数
     */
    private volatile int state = 0;

    /**
     * 当前持有锁的线程
     */
    private Thread lockHolder;

    static  {
        Field theUnsafe = null;
        try {
            theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        theUnsafe.setAccessible(true);
        try {
            unsafe = (Unsafe) theUnsafe.get(null);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    private static final long stateOffset;

    static {
        try {
            stateOffset = unsafe.objectFieldOffset(MyLock.class.getDeclaredField("state"));
        } catch (NoSuchFieldException e) {
            throw new Error();
        }
    }

    // 等待队列
    private static ConcurrentLinkedQueue <Thread> queue = new ConcurrentLinkedQueue<>();

    public static Unsafe getUnsafe() {
        return unsafe;
    }

    public static void setUnsafe(Unsafe unsafe) {
        MyLock.unsafe = unsafe;
    }

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }

    public Thread getLockHolder() {
        return lockHolder;
    }

    public void setLockHolder(Thread lockHolder) {
        this.lockHolder = lockHolder;
    }

    public static long getStateOffset() {
        return stateOffset;
    }

    public final boolean compareAndSwapState(int oldValue, int newValue) {
        return unsafe.compareAndSwapInt(this, stateOffset, oldValue, newValue);

    }

    private boolean tryAquire() {
        int state = getState();
        if (state == 0) {
            // 可以加
            if ((queue.size() == 0 || queue.peek() == Thread.currentThread()) //为0和,判断是否是队列的头部。
                && compareAndSwapState(0, 1)) {
                lockHolder = Thread.currentThread();
                return true;
            }
        }
        return false;
    }

    public void lock() {
        // 获取锁,CAS
        if (tryAquire()) {
            return;
        }
        Thread current = Thread.currentThread();
        queue.add(current);
        // 停留在当前方法
        while (true) {
            // 队列头先获取
            if (queue.peek() == current && tryAquire()) {
                System.out.println("hold lock thread-name" + current.getName());
                return;
            }
            // 阻塞线程
            LockSupport.park(current);

        }

        // 锁释放后,再次获得
    }

    public void unlock() {
        // 不合法的
        if (queue.peek() != Thread.currentThread()) {
            throw new RuntimeException();
        }

        Thread current = Thread.currentThread();
        int state = getState();
        if (compareAndSwapState(1, 0)) {
            System.out.println("hold lock thread-name" + current.getName() + " 释放成功");
            setLockHolder(null);
            Thread headThread = queue.peek();
            if (headThread != null) {
                // 解开阻塞。
                LockSupport.unpark(headThread);
            }
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值