volatile可以说是最轻量级的同步工具,但是要使用volatile来保证业务的安全和一致性,我们需要对其用法有一个认识。
被volatile修饰的变量具备两个特征,1、它可以保证此变量对所有线程的可见性,既当一个线程修改了这个变量的值,新值对于其它线程来说可以立即得知;2、防止指令重排序
要用volatile至少要满足一下两个特点:1、能够确保只有单一的线程修改变量的值;2、变量不需要与其他的状态变量共同参与不变约束。
volatile可以保证指令重排,是指,在对该变量赋值后,多执行了一个 lock addl的指令操作,相当于一个内存屏障,既不能把屏障后面的指令重排到屏障前面。该指令把修改同步到内存中,该写入动作会引起其它CPU的缓存无效,相当于对Cache中的变量做了一次Java内存模型中所说的store和write操作,因此,实现了volatile变量对其它CPU的可见性
个人觉得CAS中ABA的问题,就是通过每一次写的操作都设置一个内存屏障,写入主内存后记录一个版本号来解决的,当然有可能不对
volatile:借助硬件实现,回到内存模型,对个线程将变量拷贝到自己的缓存中,供线程使用,当有线程修改了自己的缓存变量,会将其它缓存汇总的变量置为无效,
再通过CAS操作(原子的)写入共享内存,此时会锁住总线直到完成CAS,其它缓存再去共享内存中读新的值