双重检验锁(dcl)饿汉单例模式,CAS与Synchronized区别,ABA问题解决


1.双重检验锁(dcl)饿汉单例模式

package program.singleton;
//饿汉式
public class Lsingleton {
    //声明volatile
    private volatile static Lsingleton instance;
    private Lsingleton(){ }
    public static Lsingleton getInstance(){
        if(instance==null){
            synchronized (Lsingleton.class){
                if(instance==null){
                    instance=new Lsingleton();
                }
            }

        }
        return instance;
    }
}

为什么需要加上volatile关键字修饰变量呢?

在这里插入图片描述

2.CAS是什么?

CAS→Unsafe→CAS底层→ABA→原子引用更新→规避ABA

Compare And Set(或者说Compare And Swap,根据它调用的native method说),从内存某一时刻取出数据并在当下时刻比较并替换,是一条cpu执行原语。 CAS+自旋锁

使用Unsafe类与自旋锁,根据内存地址偏移量获取数据。

线程从主内存中读取值,保存在各自的私有线程工作内存中,

修改此值并写入主内存中,

CAS会从主内存读取并且判断与给定初值是否相等,

如果是相等,则修改写入主内存,否则继续获取主内存值直到修改成功。

在这里插入图片描述
在这里插入图片描述

3.CAS与Synchronized区别

Synchronized:可以保证数据一致性,

  • 由于在线程间加锁,降低了系统的并发性。

CAS:可以保证数据一致性,不加锁并发性加强,

  • 需要多次循环(自旋锁)开销大,
  • 只能保证一个共享变量的原子操作,
  • 引出"ABA"问题

4."ABA"问题以及解决方法

CAS(Compare And Set)发生时,会从内存某一时刻取出数据并在当下时刻比较并替换,那么再这个时间差类会导致数据发生变化,也就是“ABA”问题。

概念

简单的来说,发生CAS时,因为需要从内存中读取值,比较并替换,在这个时间差中,会使得原本为A的数据由A->B->A,虽然程序依旧可以正常执行,但是不能说他是正常处理的。(狸猫换太子)

解决方法

原子引用+版本号(时间戳,类似于乐观锁)

AtomicStampReference(初始值,更新值,初始版本号,修改版本号)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值