Java中volatile的使用

零、前期准备

三大性质,原子性,可见性,有序性简绍:https://www.jianshu.com/p/cf57726e77f2

首先说下volatile的性质:可见性,有序性。

一、结合实例说明

1,结合单例模式说明

单例模式的其中一种实现:

public class Singleton {
//	private volatile static Singleton instance = null;
	private static Singleton instance = null;

	private Singleton() {}

	public static Singleton getInstance() {
		// 1,第一个IF判断
		if (instance == null) {
			// 2,同步代码块
			synchronized (Singleton.class) {
				// 3,第二个IF判断
				if (instance == null) {
					// 4,实例化对象
					instance = new Singleton();
				}
			}
		}
		// 5,返回对象
		return instance;
	}
}

现在线程t1,t2同时执行第1步;

执行第2步的时候,t1拿到了锁,t2进入等待,此时t1的instance等于null,t2的instance等于null;
t1执行完同步代码块之后,t2开始执行同步代码块,那么重点来了,
t2执行第3步的时候,此时t2的instance是否等于null?

如果等于null的话,instance声明的时候前面必须要加volatile,
因为volatile声明的变量具有可见性,当t1静态代码块执行完成之后,会告诉t2,instance已经被改变,
这样t2执行第3步时,执行结果为false,不会继续往下执行,从而保证该类的实例单一性。

事实上,此时t2的instance并不等于null。那么为什么instance明明没有加volatile声明,而t2的instance却不为null?
下面引用别人博客的话来解释(博文地址:https://www.jianshu.com/p/d53bf830fa09):


synchronized代码块中一个线程释放锁的时候会将值刷新到主内存中,其他线程获取锁时会强制从主内存中获取最新的值。


这就解释了为什么不用加volatile,t2的instance会不等于null。

实际上,我最初反复始测试的时候,就没加volatile声明,但是每个线程拿到的实例却都是相同的,这就让我很疑惑,后来我看到了这篇博文就豁然开朗,其实synchronized拥有三大性质,即原子性,可见性,有序性。所以t2执行第3步的时候,instance不等于null。

 

其它的应用场景等遇到了,再更新,上面的貌似和volatile本身没多大关系。。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值