volatile

Posted 小黑妹007

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了volatile相关的知识,希望对你有一定的参考价值。

任何被volatile修饰的变量,都不拷贝副本到工作内存,任何修改都及时写在主存。
因此对于Valatile修饰的变量的修改,所有线程马上就能看到,
但是volatile不能保证对变量的修改是有序的。什么意思呢?假如有这样的代码:
Java代码 public class VolatileTest{
public volatile int a;
public void add(int count){
a=a+count;
}
}
当一个VolatileTest对象被多个线程共享,
a的值不一定是正确的,
因为a=a+count包含了好几步操作,而此时多个线程的执行是无序的,
因为没有任何机制来保证多个线程的执行有序性和原子性。
volatile存在的意义是,任何线程对a的修改,
都会马上被其他线程读取到,因为直接操作主存,没有线程对工作内存和主存的同步
。所以,volatile的使用场景是有限的,在有限的一些情形下可以使用 volatile 变量替代锁。
要使 volatile 变量提供理想的线程安全,必须同时满足下面两个条件:
1)对变量的写操作不依赖于当前值。
2)该变量没有包含在具有其他变量的不变式中
volatile只保证了可见性,所以Volatile适合直接赋值的场景,
如Java代码
public class VolatileTest{
public volatile int a;
public void setA(int a){
this.a=a;
}
}
public class VolatileTest{
public volatile int a;
www.gzlij.com public void setA(int a){
this.a=a;
}
}
4在没有volatile声明时,多线程环境下,a的最终值不一定是正确的,
因为this.a=a;涉及到给a赋值和将a同步回主存的步骤,这个顺序可能被打乱。
如果用volatile声明了,读取主存副本到工作内存和同步a到主存的步骤,
相当于是一个原子操作。
所以简单来说,volatile适合这种场景:一个变量被多个线程共享,线程直接给这个变量赋值。
这是一种很简单的同步场景,这时候使用volatile的开销将会非常小。
 

以上是关于volatile的主要内容,如果未能解决你的问题,请参考以下文章

volatile

volatile

volatile原理解析

注意,不能错过的CAS+volatile实现同步代码块

注意,不能错过的CAS+volatile实现同步代码块

注意,不能错过的CAS+volatile实现同步代码块