Java 多线程的线程安全需要保证原子性和可见性,volatile 关键字可以保证可见性不能保证原子性,synchronized 关键字可以保证可见性和原子性,不过有几点疑问请教一下大佬:
(1)volatile 关键字如何保证的可见性,在书上和博客上看到了两种不同的说法,不知道哪种正确:
1.赋值操作后会立即写回主内存,一个线程数据回写到主内存会导致其他线程对应数据无效(通过嗅探总线上传输的数据检查自身数据),线程下次使用时若发现自身数据失效,则会从主内存上取数据更新;
2.线程中每次 use 变量时,都需要连续执行 read->load->use 几项操作保证使用的数据是最新的,线程每次 assign 变量时,都需要连续执行 assign->store->write 几项操作,保证赋值后立即写回主内存;
(2)未使用 volatile 关键字的普通变量赋值后工作内存写回主内存的时机: volatile 关键字修饰的变量赋值语句后会立即写回主内存,普通变量赋值修改后什么时候写回主内存呢,是当一个方法执行完后吗?
(3)volatile 使用内存屏障解决指令重排序带来的线程安全问题,synchronized 是怎么解决指令重排序带来的线程安全问题的呢?
其实运用volatile关键字主要解决的问题是:主存和私有内存共享变量不同步的问题,
(1)在JMM(内存模型)中私有内存也就是本地内存存储的是共享变量的副本,线程进行操作时,先把主存中的共享变量刷新到本地内存中,当本地内存共享变量副本更新后,又将共享变量副本的值刷新到主存中,volatile关键字使用,保证了可见性,强制从主存中获取共享变量的值。
(2)个人认为普通变量和volatile的写回内存的时机是一致的,使用volatile解决的是本地内存和主存变量不一致的问题,只是用volatile修饰的变量是强制从主存中获取变量值,而普通变量是从本地内存中获取变量值
(3)第三点由于个人能力还不够 暂时不能回答
以上都是个人总结的观点,若有说错的地方 还请原谅