双重检查锁模式的应用

双重检查锁模式的应用


双重检查锁定模式,关键要素 volatilesynchronized 除了用于防止接口被重复调用以外,还可以用于创建单例对象。
1应用场景及思想

  • 单例模式:首先判断变量是否被初始化,没有被初始化,再去获取锁。获取锁之后,再次判断变量是否被初始化。 第二次判断目的在于有可能其他线程获取过锁,已经初始化改变量。第二次检查还未通过,才会真正初始化变量。
  • 防止接口重复调用:适用于花费时间比较长的接口,先定义一个volatile修饰的初始值为falseboolean变量作为标志位,首先判断这个标志位是否为false,发现这个接口没有被调用后再去获取线程同步锁,获取到锁之后再次判断该标志位是否为false,第二次检查该接口还未被调用就开始执行真正的调用逻辑

2优点

  • 比单纯的仅仅使用线程同步锁synchronized,缩小锁了的范围,减少了锁的开销
  • 为什么要用 volatile 来修饰变量呢?主要是为了解决指令重排问题,而volatile主要包含两个功能。
    1)、是保证可见性:使用 volatile定义的变量,将会保证对所有线程的可见性。
    2)、禁止指令重排序优化。
    因此由于 volatile禁止对象创建时指令之间的重排序,所以其他线程不会访问到一个未初始化的对象,从而保证安全性。
    注意:那么指令重排有什么危害呢?首先指令重排主要针对创建对象的场景,众所周知,new(创建对象)并不是一个原子指令,使用 javap -c指令可以看到
  • 创建一个对象实例,可以分为三步:
      1、分配对象内存
      2、调用构造器方法,执行初始化
      3、将对象引用赋值给变量。

虚拟机实际运行时,以上指令可能发生重排序。也就是说以上方法执行的第 2,3 步可能发生重排序,但是并不会重排序 1 的顺序。也就是说 1 这个指令都需要先执行因为 2,3 指令需要依托 1 指令执行结果,Java 语言规规定了线程执行程序时需要遵守 intra-thread semantics。intra-thread seman

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值