关于 Java 多线程的几点疑问,求助大佬

新手上路,请多包涵

Java 多线程的线程安全需要保证原子性和可见性,volatile 关键字可以保证可见性不能保证原子性,synchronized 关键字可以保证可见性和原子性,不过有几点疑问请教一下大佬:

(1)volatile 关键字如何保证的可见性,在书上和博客上看到了两种不同的说法,不知道哪种正确:

1.赋值操作后会立即写回主内存,一个线程数据回写到主内存会导致其他线程对应数据无效(通过嗅探总线上传输的数据检查自身数据),线程下次使用时若发现自身数据失效,则会从主内存上取数据更新;

2.线程中每次 use 变量时,都需要连续执行 read->load->use 几项操作保证使用的数据是最新的,线程每次 assign 变量时,都需要连续执行 assign->store->write 几项操作,保证赋值后立即写回主内存;

(2)未使用 volatile 关键字的普通变量赋值后工作内存写回主内存的时机: volatile 关键字修饰的变量赋值语句后会立即写回主内存,普通变量赋值修改后什么时候写回主内存呢,是当一个方法执行完后吗?

(3)volatile 使用内存屏障解决指令重排序带来的线程安全问题,synchronized 是怎么解决指令重排序带来的线程安全问题的呢?

阅读 2.6k
2 个回答

其实运用volatile关键字主要解决的问题是:主存和私有内存共享变量不同步的问题,

(1)在JMM(内存模型)中私有内存也就是本地内存存储的是共享变量的副本,线程进行操作时,先把主存中的共享变量刷新到本地内存中,当本地内存共享变量副本更新后,又将共享变量副本的值刷新到主存中,volatile关键字使用,保证了可见性,强制从主存中获取共享变量的值。

(2)个人认为普通变量和volatile的写回内存的时机是一致的,使用volatile解决的是本地内存和主存变量不一致的问题,只是用volatile修饰的变量是强制从主存中获取变量值,而普通变量是从本地内存中获取变量值

(3)第三点由于个人能力还不够 暂时不能回答

以上都是个人总结的观点,若有说错的地方 还请原谅

我记得synchronized并未从JVM的角度作出任何有关重排序的规范,这一般依赖于你的JVM实现。比如有的JVM会把synchronized从一个同步块提升为同步整个方法,从而避免了重排序所造成的问题。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题