volatile、synchronized、static多线程运用(个人理解)

        java主要有两套内存模型,一套是JVM对Java内存模型的实现、另一套是硬件内存架构。其中,Java内存模型由“线程栈区”和“堆区”组成,是虚拟存在的,而硬件内存架构由“CPU寄存器(储存器)”、“CPU缓存”、“主存”三者构成,是真实存在的。

        这两套模型的关系如下(左边是Java内存模型、右边是硬件内存模型):

        可以发现,两套模型的对应关系相当复杂,即“线程栈区”和“堆区”中的数据可能存在于“CPU寄存器(储存器)”、“CPU缓存”、“主存”三者中的任一中。

        当读取volatile和synchronized修饰的数据时,都必须去“主存”中去读取,然后在“CPU缓存”中操作。而修改volatile和synchronized修饰的数据时,则会先去“主存”中读取数据,然后在“CPU缓存”中完成操作后立即把修改后的值返回给“主存”中,二者的区别在于:当并行访问来修改同一数据时,volatile不能保证数据的一致性,而synchronized可以。例如:

        如下图所示,线程A和线程B共享一个对象obj。假设线程A从主存读取Obj.count变量到自己的CPU缓存,同时,线程B也读取了Obj.count变量到它的CPU缓存,并且这两个线程都对Obj.count做了加1操作。此时,Obj.count加1操作被执行了两次,不过都在不同的CPU缓存中。

        如果这两个加1操作是串行执行的,那么Obj.count变量便会在原始值上加2,最终主存中的Obj.count的值会是3。然而下图中两个加1操作是并行的,不管是线程A还是线程B先flush计算结果到主存,最终主存中的Obj.count只会增加1次变成2,尽管一共有两次加1操作。


        volatile和static的功能类似,其区别在于,volatile修饰的变量在修改后立即同步到“主存”中,而static不会立即同步到“主存”中。

        参考文档 :

        1.https://blog.csdn.net/suifeng3051/article/details/52611310

        2.https://blog.csdn.net/suifeng3051/article/details/52611233

        3.https://www.zhihu.com/question/41579791




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值