java的内存可见性分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/axiaoboge/article/details/82503374

java多线程之内存可见性
共享变量在线程间的可见性
Synchronized实现可见性
volatile实现可见性
     指令重排序
     as if -serial语意
     volatile使用注意事项
Synchronized和volatile的比较

1.可见性介绍
    可见性:一个线程对共享变量的修改,能够及时的被其他线程看到
    共享变量:如果一个变量在多个线程中存有副本,那么这个变量就是这几个线程的共享变量
    java内存模型(JMM)
    java内存模型(java memory model)描述了java程序中各种变量(线程共享变量)的访问规则,以及在jvm中将变量储存到内存
    和从内存中读取出变量的底层细节。

2.通过Synchronized和volatile都可以实现可见性
  线程对共享变量的所有操作都必须在自己的工作内存中进行
  所有的变量都储存在主内存中

3.要实现共享变量的可见性,必须保证二点
  线程修改后的共享变量值能够及时保证从工作内存中刷新到主内存中。
  其他线程能够及时把共享变量的最新值从主内存中刷新到自己的工作内存中去。

4.可见性的实现方式
java语言支持的可见性实现方式
synchronized和volatile
1.)Synchronized能够实现
原子性,同步


JMM关于Synchronized的二条规定:
1.1 线程解锁前,必须把共享变量的最新值刷新到主内存中去
1.2 线程加锁时,将清空工作内存中共享变量的值,从而使用共享变量时需要从主内存重新读取最新的值
(注意:加锁和解锁需要同一把锁)
线程解锁前对共享变量的修改在下次加锁时对其他线程可见
线程执行互斥锁代码的过程
1,获得互斥锁
2,清空工作内存
3,从主内存中拷贝最新副本的变量到工作内存中
4,执行代码
5,将更改后共享变量的值刷新到主内存中
6,释放互斥锁

重排序:
代码书写的顺序与实际执行的顺序不同,指令重排序是编译器或处理器为了
提高程序性能做的优化
1.编译器优化的重排序(编译器优化)
2.指令级并行重排序(处理器优化)
3.内存系统的重排序(处理器优化)

as-if-serial
as-if-serial:无论如何重排序,程序执行的效果应该与代码的顺序执行的结果一致
(java编辑器,运行时和处理器都会保证java在单线程下遵守as-if-serial语句)

导致共享变量在线程间不可见的原因
1. 线程的交叉执行                                                                                       原子性
2. 重排序结合线程交叉执行                                                                         原子性
3. 共享变量更新后的值没有在工作内存与主内存之间及时更新                    可见性

猜你喜欢

转载自blog.csdn.net/axiaoboge/article/details/82503374