volatile有感

·  阅读 67

在说volatile关键字之前先来说一说java内存模型

在多线程读写情景下,会出现线程2读到的a=0,而实际上线程1已经把a为a=1了,出现了数据不一致情况

volatile遵循MESI(缓存一致性协议),通俗来说就是assign赋值操作后要紧跟着进行store和write操作,并且将其他线程工作内存中的 a变量缓存无效,嗅探机制使线程2知道了a值已经更新,会马上从主内存拉取最新的值

可见 volatile保证了可见性

那为什么说volatile不保证原子性呢? 也可以从上面那图接着讲,若线程1和线程2都执行的是a++的操作,都是use a=0,线程1 a++后a=1了,然后assign,store,write,使线程2工作内存中的a变量缓存无效,线程2又会马上从主内存读到新a=1加载到工作内存中去。但是此时线程2中并不需要再去从工作内存中去读a,所有a++后a=1,并不是2

volatile底层实现原理 内存屏障

LoadLoad屏障:对于这样的语句Load1; LoadLoad; Load2,在Load2及后续读取操作要读取的数据被访问前,保证Load1要读取的数据被读取完毕。

StoreStore屏障:对于这样的语句Store1; StoreStore; Store2,在Store2及后续写入操作执行前,保证Store1的写入操作对其它处理器可见。

LoadStore屏障:对于这样的语句Load1; LoadStore; Store2,在Store2及后续写入操作被刷出前,保证Load1要读取的数据被读取完毕。

StoreLoad屏障:对于这样的语句Store1; StoreLoad; Load2,在Load2及后续所有读取操作执行前,保证Store1的写入对所有处理器可见

分类:
阅读
标签:
分类:
阅读
标签: