CAS自旋锁

手写自旋锁

复制代码
public class SpinLockDemo {

        AtomicReference<Thread> atomicReference = new AtomicReference<>();

        public void lock(){
            Thread thread = Thread.currentThread();
            System.out.println(thread.getName()+ " --- come in");
            //while循环持续尝试拿锁,成功了才能跳出循环
            while (!atomicReference.compareAndSet(null, thread)){

            }
        }

        public void unlock(){
            Thread thread = Thread.currentThread();
            atomicReference.compareAndSet(thread,null);
            System.out.println(thread.getName()+ " --- task over, unlock");
        }
}
复制代码

CAS的两大缺点

1,循环时间长,性能开销很大。

2,会导致"ABA"问题:CAS算法的一个重要前提需要取出内存中某时刻的数据并在当下时刻比较并替换,那么在这个时间差类会导致数据的变化

  比如说一个线程1从内存位置V中取出A,这时候另一个线程2也从内存中取出A,并且线程2进行了一些数值操作变成了B,然后线程2又将V位置的数据变成A,这时候线程1进行CAS操作发现内存中仍然是A,预期OK,然后线程1操作成功。

  尽管线程1的CAS操作成功,但是不代表这个过程就是没有问题的。

如何避免ABA问题?  

使用AtomicStampedReference,也就是带有版本号的AtomicReference

//构造器:Book (类名) javabook (实例对象) 1 (版本号)

AtomicStampedReference<Book>  stampedReference = new AtomicStampedReference<>(javaBook, 1)

//CAS方法:括号内依次为(预期对象,新对象,预期版本号,新版本号)

boolean flag = stampedReference.compareAndSet(javaBook, mysqlBook, stampedReference.getStamp(), stampedReference.getStamp()+1)

 

posted @   wwwwwwwty  阅读(43)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示