标签:编程 margin mamicode 检查 因此 需要 [] 空间 sync
一、volatile的使用
1、防止重排序
public class Singleton {
public static volatile Singleton singleton;
private Singleton() {}
public static Singleton getInstance() {
if(singleton == null) {
synchronized (singleton) {
if(singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
实例化一个对象其实可以分为三个步骤:
(1)分配内存空间
(2)初始化对象
(3)将内存空间的地址赋值给对应的引用。
但是由于操作系统可以对指令进行重排序,所以上面的过程也可能变成如下过程:
(1)分配内存空间
(2)将内存空间的地址赋值给对应的引用。
(3)初始化对象
如果这是个流程,多线程环境下就可能将一个未初始化的对象引用暴露出来,从而导致不可预料的结果。因此,为了防止这个过程的重排序,我们需要将变量设置为volatile类型的变量。
2、实现可见性
public class VolatileTest { int a = 1; int b = 2; public void change() { a = 3; b = a; } public void print() { System.out.println("b=" + b + ";a=" + a); } public static void main() { final VolatileTest bean = new VolatileTest(); new Thread(new Runnable() { public void run() { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } bean.change(); } }).start(); new Thread(new Runnable() { public void run() { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } bean.print(); } }).start(); } public static void main(String[] args) { for(int i = 0; i < 10; i++) { main(); } } }
直观上说,这段代码的结果只可能有两种:b=3;a=3或者b=2;a=1。不过运行上面的代码,却出现了三种情况:
标签:编程 margin mamicode 检查 因此 需要 [] 空间 sync
原文地址:https://www.cnblogs.com/lynn16/p/10705895.html