为了提高处理速度,处理器不直接和内存通信,会将系统内存的数据读取到内部缓存再操作,操作完成后写入内存的时机未知
因此对于多线程操作的共享变量,如:单例对象、状态标记变量(flag),可以使用volatile修饰保证其多线程环境的可见性
volatile是轻量级的synchronized
可见性
当一个线程修改一个变量时,另一个线程可以读到修改后的值。
对volatile写操作:JMM(Java Memory Model)会将本地内存中的变量值刷新到主内存
对volatile读操作:JMM会将本地内存置为无效,从主内存中读取变量值
原子性
读操作和写操作都有原子性,但是复合操作不具备原子性。
例如:i++,包含读取、运算、写入三个操作
有序性
禁止指令重排
为什么要禁止指令重排?
- 语句可能带有隐式因果关系
- 多线程环境下,指令重排可能会导致线程安全问题