在程序设计中,尤为是在C语言、C++、C#和Java语言中,使用volatile关键字声明的变量或对象一般拥有和优化和(或)多线程相关的特殊属性。一般,volatile关键字用来阻止(伪)编译器对那些它认为变量的值不能“被代码自己”改变的代码上执行任何优化。 在C环境中,volatile关键字的真实定义和适用范围常常被误解,加之C++、C#和Java都从C中神秘地“继承”了volatile,在这些编程语言中,所以这些语言中volatile的用法和语义截然不同。编程
Java也支持volatile关键字,但它被用于其余不一样的用途。当volatile用于一个做用域时,Java保证以下:缓存
1.(适用于Java全部版本)读和写一个volatile变量有全局的排序。也就是说每一个线程访问一个volatile做用域时会在继续执行以前读取它的当前值,而不是(可能)使用一个缓存的值,直接从主存中读取,避免编译器优化。(可是并不保证常常读写volatile做用域时读和写的相对顺序,也就是说一般这并非有用的线程构建)。多线程
2.(适用于Java5及其以后的版本)volatile的读和写创建了一个happens-before关系,相似于申请和释放一个互斥锁。并发
这时,联想到的另外一个关键词即是synchronized.可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这个段代码。当两个并发线程访问同一个对象object中的这个加锁同步代码块时,一个时间内只能有一个线程获得执行。另外一个线程必须等待当前线程执行完这个代码块之后才能执行该代码块。然而,当一个线程访问object的一个加锁代码块时,另外一个线程仍然能够访问该object中的非加锁代码块。app
所以,两个关键词的区别以下:jvm
1.volatile本质是在告诉jvm当前变量在寄存器(工做内存)中的值是不肯定的,须要从主存中读取;synchronized则是锁定当前变量,只有当前线程能够访问该变量,其余线程被阻塞住。编程语言
2.volatile仅能使用在变量级别;synchronized则可使用在变量、方法、和类级别的。优化
3.volatile仅能实现变量的修改可见性,并能保证原子性;而synchronized则能够保证变量的修改可见性和原子性。spa
4.volatile不会形成线程的阻塞;synchronized可能会形成线程的阻塞。 线程
5.volatile标记的变量不会被编译器优化;synchronized标记的变量能够被编译器优化。