JUC并发编程—— 对volatile的理解及DCL的解决方法

volatile的原理

volatile 的底层实现原理是内存屏障,Memory Barrier(Memory Fence)

加入 volatile 关键字后,写指令(被 volatile 修饰的变量在对此变量修改时)会加入写屏障,读指令(被 volatile 修饰的变量在对此变量读取时)会加入读屏障。

  • 写屏障:
    • 保证有序性:不会将写屏障之前的代码排在写屏障之后
    • 保证可见性:保证在写屏障之前,对共享变量的修改,都同步到主存中
  • 读屏障
    • 保证有序性:不会将读屏障之后的代码排在读屏障之前
    • 保证可见性:保证在读屏障之后,对共享变量的读取,加载的是主存中最新的数据

double-checked locking 问题

由 double-checked locking 单例模式为例

public final class Singleton {
	private Singleton (){}
	private static Singleton INSTANCE = null;
	public static Singleton getInstance(){
		if(INSTANCE == null){
			synchronized(Singleton.class) {
				if(INSTANCE == null){
					INSTANCE = new Singleton();
				}
			}
		}
		return INSTANCE;
	}
}

关键的字节码部分 =》可能出现指令重排序(21 和 24 顺序互换)

...
17: new 			#3 		// class com/zhl/n5/Singleton
20: dup
21: invokespecial 	#4 		// Method "<init>":()V
24: putstatic 		#2 		// Field INSTANCE:Lcom/zhl/n5/Singleton;
...

在这里插入图片描述

double-checked locking 解决

在 INSTANCE 对象加上 volatile 关键字,禁用重排序,保证有序性。

private static volatile Singleton INSTANCE = null;
  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值