亲宝软件园·资讯

展开

Java关键字volatile Java并发编程之关键字volatile知识总结

菜鸟日常 人气:0
想了解Java并发编程之关键字volatile知识总结的相关内容吗,菜鸟日常在本文为您仔细讲解Java关键字volatile的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:Java关键字volatile,Java关键字,下面大家一起来学习吧。

一、作用

被 volatile 修饰的变量

1.保证了不同线程对该变量操作的内存可见性

2.禁止指令重排序

二、可见性

在这里插入图片描述

Java 内存模型(Java Memory Model) 是 Java 虚拟机定义的一种规范,即每个线程都有自己的工作空间,线程对变量的操作都在线程的工作内存中完成,再同步到主存中,这样可能会导致不同的线程对共享变量的操作,在各自线程工作空间内不一样的问题。

而用 volatile 修饰的变量,线程对该变量的修改,会立刻刷新到主存,其它线程读取该变量时,会重新去主存读取新值。

三、有序性

CPU 为了提供程序的运行效率,会对代码的执行顺序进行重排,因此代码中各个语句的先后执行顺序有可能会变化,但是它会保证程序最终执行结果与代码顺序执行结果一致。

指令重排序会考虑数据之间的依赖性,不会影响单个线程内程序的执行结果

c = 2 可能在 a = 1之前执行

int a = 1;
int c = 2;

volatile 修饰的变量具有有序性,即被 volatile 修饰的变量,在其前面的操作与在其后面的操作的执行顺序不能打乱。

int a= 1;
volatile b = 2;
int c = 2;

a = 1 一定在 c = 2 前面执行,volatile 的作用好像在两者之间插入了一个内存屏障

对于 volatile 的有序性应用,一般常用 double-check 的单例模式来说明

public class Singleton {
	private Singleton(){}

	private static volatile Singleton singleton;
	
	public static Singleton getSingleton(){
		if (singleton == null){
			synchronized(Singleton.class){
				if (singleton == null){
					singleton = new Singleton();
				}
			}
		}
		return singleton		
	}
}

singleton = new Singleton(); 分为 3 步

1.new Singleton() 开辟堆内存空间

2.初始化 singleton 对象

3.将 singleton 对象指向堆内存地址

第 3 步可能在第 2 步之前执行,那么其它线程可能得到为初始化完成的 singleton 对象,造成异常。

四、happens-before

五、与 Synchronized 对比

1.volatile 只能作用于变量,synchronized 可以作用于变量,方法,代码块

2.volatile 不保证原子性,synchronized 可以保证

3.访问 volatile 修饰的变量不会阻塞,synchronized 可能会

加载全部内容

相关教程
猜你喜欢
用户评论