在只有双重检查锁,没有Volatile的懒加载单例模式中,由于指令重排序的问题,我确实不 会拿到两个不同的单例了,但我会拿到“半个”单例。
而发挥神奇作用的volatile,可以当之无愧的被称为Java并发编程中"出现频率最高的关键字”,常用于保持内存可见性和防止指令重排序。
保持内存可见性
内存可见性(Memory Visibility):所有线程都能看到共享内存的最新状态。
失效数据
以下是一个简单的可变整数类:
public class Mutablelnteger {
private int value;
public int get() {
return value;
}
public void set(int value){
this.value = value;
}
}
Mutablelnteger不是线程安全的,因为get和set方法都是在没有同步的情况下进行的。如 果线程1调用了 set方法,那么正在调用的get的线程2可能会看到更新后的value值,也可 能看不到。
解决方法很简单,将value声明为volatile变量:
private volatile int value;
神奇的volatile关键字
神奇的volatile关键字解决了神奇的失效数据问题。
Java变董的读写
Java通过几种原子操作完成工作内存和主内存的交互:
1、 lock:作用于主内存,把变量标识为线程独占状态。
2、 unlock:作用于主内存,解除独占状态。
3、 read:作用主内存,把一个变量的值从主内存传输到线程的工作内存。
4、 load:作用于工作内存,把read操作传过来的变量值放入工作内存的变量副本中。
5、 use:作用工作内存,把工作内存当中的一个变量值传给执行引擎。
6、 assign:作用工作内存,把一个从执行引擎接收到的值赋值给工作内存的变量。
7、 store:作用于工作内存的变量,把工作内存的一个变量的值传送到主内存中。
8、 write:作用于主内存的变量,把store操作传来的变量的值放入主内存的变量中。
Was this helpful?
0 / 0