volatile关键字的内存语义

volatile关键字的理解

当我们声明一个变量为 volatile 时,程序对于该变量的读和写就会变得十分特别,具体的特别之处,我们还是要看看 volatile 关键字的内存语义,观察其特别之处。

下面是一个简单的例子,通过这个例子我们来具体说明 volatile 关键字的内存语义

class VolatileFeatures {
	volatile long value = 0L;
	pulbic void set(long val) {
		value = val;
	}
	public void getIncreament() {
		value++;
	}
	public long get() {
		return value;
	}

这看似是一个简单的例子,在一个类里面定义变量,给出对应的@Setter 和 @Getter 方法。但是,我们定义的变量使用了 volatile 关键字进行修饰。这也正是特殊之处,当我们在程序中进行调用此处的 value 变量时,对其进行读写操作,相当于对一个普通变量使用同一个锁来同步,二者的执行效果是相同的。所以,上面的案例可以等同于下面的例子

class TheSameAsVolatileFeatures {
	//定义一个普通变量
	long value = 0L;
	//对普通变量的写操作使用同一个锁进行同步
	public synchronized void set(long val) {
		value = val;
	}
	//对于普通变量进行普通操作
	public void getIncreament() {
		//调用同步读方法
		long v = get();
		//进行普通操作
		v += 1L;
		//调用同步写方法
		set(v);
	}
	//对普通变量的读操作使用同一个锁进行同步
	public synchronized long get() {
		return value;
	}

通过上面的例子可以看出,由于锁的happens-before原则保证了释放锁与获取锁的两个线程内存可见,这也就是我们 volatile 关键字的特殊之处

对于一个 volatile 变量的读,总能看到任意线程对于该变量最后的写入

至此可以总结出, volatile 变量有一下特性

可见性:对于一个 volatile 变量的读,总能看到任意线程对于该 volatile 变量的最后写入。
原子性:对任意单个 volatile 变量的读与写均具有原子性,但是,类似于 volatile++ 这种复合操作,将不再具有原子性。

volatile 关键字的内存语义

讲到内存语义这块,volatile 变量的读 - 写 与锁的释放 - 获取具有相同的内存效果:

volatile写和锁的释放具有相同的内存语义
volatile读和锁的获取具有相同的内存语义

综合来说的话,volatile 关键字的读写内存语义总结如下:

1、线程A写一个 volatile 变量,实质上是线程A向接下来将要读该 volatile 变量的线程发出了(对于共享变量进行修改)消息。
2、线程B要读一个 volatile 变量,实质上是线程B收到了之前某个线程修改共享变量的消息,这样保证了该变量的一致性和同步性。
3、线程A写 volatile 变量,线程B读 volatile 变量,实质上二者的信息交流是通过主内存(共享内存)来进行的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值