volatile梳理
volatile
- 可见性也就是说一旦某个线程修改了该被volatile修饰的变量,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,可以立即获取修改之后的值。
在Java中为了加快程序的运行效率,对一些变量的操作通常是在该线程的寄存器或是CPU缓存上进行的,之后才会同步到主存中,而加了volatile修饰符的变量则是直接读写主存。 - Volatile 保证了线程间共享变量的及时可见性,但不能保证原子性
- 禁止指令重排序优化。有volatile修饰的变量,赋值后多执行了一个“load addl $0x0, (%esp)”操作,这个操作相当于一个内存屏障(指令重排序时不能把后面的指令重排序到内存屏障之前的位置),只有一个CPU访问内存时,并不需要内存屏障;(什么是指令重排序:是指CPU采用了允许将多条指令不按程序规定的顺序分开发送给各相应电路单元处理)。
- volatile 的读性能消耗与普通变量几乎相同,但是写操作稍慢,因为它需要在本地代码中插入许多内存屏障指令来保证处理器不发生乱序执行。
- 项目中,只要是全局共享变量,全部都是加上Volatile的。
- Volatile与Synchronized区别
(1)Synchronized可以保证内存可见性和操作原子性。
(2)Volatile只能保证内存可见性
(3) Volatile不需要加锁,比Synchronized更轻量级,并不会阻塞线程,而Synchronized可能造成线程阻塞。
(4) Volatile标记的变量不会被编译器优化,而Synchronized标记的变量是可以被编译器优化的。
(5) Volatile仅是变量修饰符,而Synchronized可以修饰多种。 - Volatile本质是告诉jvm当前的变量在寄存器中的值是不确定的,使用前先从主内存中读取,因此可以实现可见性。
- Volatile对n=n+1.n++等操作时,是失效的。