自己实现一个CAS自旋锁


原理

使用原子引用类的compareAndSet设置线程到对象中,当当前值为null期望值为当前线程修改成功时加锁成功,修改失败时进行自旋。

创建MyLock对象

public class MyLock {
    AtomicReference reference= new AtomicReference(null);

    public void lock(){
        //获取当前线程
        Thread thread = Thread.currentThread();
        //添加当前线程到原子对象中,不成功开始自旋
        while(!reference.compareAndSet(null,thread)){

        }
        //添加锁成功
        System.out.println("============="+thread.getName()+"加锁成功=============");
    }

    public void unlock(){
        //获取当前线程
        Thread thread = Thread.currentThread();
        //将当前线程移除原子引用
        reference.compareAndSet(thread,null);
        System.out.println("============="+thread.getName()+"解锁成功==============");
    }
}

测试

两个线程使用同一把锁,第一个线程阻塞五秒。

public static void main(String[] args) {
        MyLock myLock = new MyLock();
        new Thread(()->{
            myLock.lock();
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                myLock.unlock();
            }
        },"A").start();

        new Thread(()->{
            myLock.lock();
            try {

            }finally {
                myLock.unlock();
            }
        },"B").start();
    }

结果

=============A加锁成功=============

5秒后

=============A加锁成功=============
=============A解锁成功==============
=============B加锁成功=============
=============B解锁成功==============