最近有点空闲时间,看了一下《Netty权威指南》,看到了关于volatile的一段论述:
自己之前纠结过一段时间,这里说一下自己的理解,volatile变量作用有两方面:可见性和防止重排序。这个就不多说了,这里主要说一下volatile变量在什么情况下可以抛弃锁。首先应该确定一个前提,就是volatile变量不能牵扯到与其它变量的不变约束中,也就是说,volatile变量的变化不会与其它变量的变化有任何联系,如果volatile变量牵扯到不变约束中,单纯的volatile肯定无法维护多个变量的并发变化。
确定了这样一个前提,我认为volatile变量在两种情况下可以完全抛弃锁:
1.单线程写,多线程读
在这种情况下,volatile变量的修改只来自一个线程,而且volatile可以保证对于该变量的修改可以及时反映给读取该变量的线程
2.多线程并发写
对于多个线程并发修改volatile变量的情况,如果赋值操作可以保证是原子的,例如java基本类型(排除long和double)的简单赋值操作,一样可以抛弃锁。这里最重要的还是对于volatile变量的修改操作是原子性的,这个原子性是由变量自身保证的,对于int型变量来说int a=10可以保证赋值操作的原子性,但是int a=++b这样的赋值操作就不能保证了。总结一下就是如果变量的修改不依赖变量的当前值并且这个变量的修改是原子的,那么在多线程并发修改该变量的情况下,简单的volatile就可以保证变量可以被正确的使用。