Java保证共享变量“可见性”的机制

阅读: 评论:0

Java保证共享变量“可见性”的机制

Java保证共享变量“可见性”的机制

Java代码在编译后会变成Java字节码,字节码被类加载器加载到JVM(Java虚拟机),JVM执行字节码,最终转化为汇编指令在cpu上执行,Java中所使用的并发机制依赖于JVM的实现和cpu的指令。
在多线程中,有时候会遇到这种问题:当一个线程修改了共享变量时,另一个线程不知道这个变量已经被修改(数据修改不是修改原始数据,而是对拷贝的数据进行修改。)了,还是使用以前的变量(存放在一个缓存中),这就会造成某些线程看到的同一个变量的值是不一样的。共享变量的“可见性”就是针对这个问题来实现的。原理如下:

这种情况怎么解决呢?Java提供了两种解决方式:volatile的应用和synchronized的应用。

volatile的应用

如果一个字段被声明成volatile,Java线程内存模型确保所有线程看到这个变量的值是一致的。下面我们详细讲解具体实现:
Java代码:
instance=new singleton();  //instance是volatile变量

转换成汇编代码为:

0x01a3deld:....;
0x01a3de24:lock addl ...

我们可以看到volatile变量修饰的共享变量进行写操作时会多出第二行汇编代码。lock前缀的指令在多喝处理器下会引发两件事:

  • 将当前处理器缓存行的数据写回到内存。
  • 写回内存的操作会使其他 cpu里缓存了该内存地址的数据无效。(通过嗅探在总线上传播的数据来检查自己缓存的值是否过期了),然后从新从内存中把数据读到缓存里。

synchronized的实现原理和应用

当一个线程试图访问同步代码块时,它首先必须得到锁,退出或抛出异常时必须释放锁。
JVM是基于进入和退出Monitor对象来实现方法同步和代码块同步,当两者实现的细节不一样: - 代码块同步是使用monitorenter和monitorexit指令实现的
- 方法同步是使用另外一种方法实现的(具体方法未知,尴尬吗!),但同样可以使用上面两个指令来实现。

本文发布于:2024-02-01 10:51:06,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170675586636099.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:变量   机制   见性   Java
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23