volatile : JVM提供的轻量级同步机制
➢保证被volatile修饰的共享变量对所有线程总是可见的,当一个线程修改了被volatile修饰的共享变量的值,其他线程立即感知到变动
➢禁止指令重排序优化
volatile变量为何立即可见?
- 当写一个volatile变量时, JMM会把该线程对应的工作内存中的共享变
量值刷新到主内存中; - 当读取一个volatile变量时, JMM会把该线程对应的工作内存置为无效。
volatile如何禁止重排优化
内存屏障( Memory Barrier )
1.保证特定操作的执行顺序
2.保证某些变量的内存可见性
通过插入内存屏障指令禁止在内存屏障前后的指令执行重排序优化强制刷出各种CPU的缓存数据,因此任何CPU_上的线程都能读取到这些数据的最新版本
volatile和synchronized的区别
- volatile本质是在告诉JVM当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取; synchronized则是锁定当前变量, 只有当前线程可以访问该变量,其他线程被阻塞住直到该线程完成变量操作为止
- volatile仅能使用在变量级别; synchronized则可以使用在变量、方法和类级别
- volatile仅能实现变量的修改可见性,不能保证原子性;而synchronized则可以保证变量修改的可见性和原子性
- volatile不会造成线程的阻塞; synchronized可能会造成线程的阻塞
- volatile标记的变量不会被编译器优化; synchronized标记的变量可以被编译器优化